关于js中同步异步、宏任务和微任务的理解
首先
1.简单理解同步异步、宏任务和微任务
js是单线程的,所有的任务都要排队挨个执行,就好比做保健(执行js代码),保健师傅只有一个(单线程),顾客(js代码)需排队享受服务,排队的顺序按照顾客的种类(同步异步、宏任务微任务)和顾客到店顺序(在代码中的位置)执行
-
同步与异步、宏任务和微任务分别是函数两个不同维度的描述。
-
异步任务:setTimeout和setInterval、ajax、事件绑定等
-
同步任务:除了异步任务外的所有任务
-
微任务:process.nextTick和 Promise后的theny语句和catch语句等
-
宏任务:除了微任务以外的所有任务
2.执行顺序判断方法
先同步再异步,在此promise中先宏任务再微任务 ,其他时候微任务执行早于其他微任务(请看promise微任务宏任务的文章)
看下面这个例子
3.简单实例分析
new Promise(function (resolve, reject) {
console.log('异步宏任务promise');
resolve();
}).then(function () {
console.log('异步微任务then')
})
console.log('异步宏任务');
}, 0)
new Promise(function (resolve, reject) {
console.log('同步宏任务promise');
resolve();
}).then(function () {
console.log('同步微任务then')
})
console.log('同步宏任务')
分析:setTimeout是异步任务,虽然他在0秒后执行但仍排在队列的后面,因此其中的代码全部靠后执行;new Promise是同步任务同时也是主任务,因此第一行先打印'同步宏任务promise',then是微任务所以靠后执行,先执行第16行代码,之后再执行第13行的then语句,因此第二行输出为'同步宏任务',第三行为'同步微任务then';接下来执行setTimeout中的语句,then因为是微任务所以在第8行执行完成后再执行。
4.稍复杂点的实例分析
setTimeout(() => {
console.log('异步1任务time1');
new Promise(function (resolve, reject) {
console.log('异步1宏任务promise');
setTimeout(() => {
console.log('异步1任务time2');
}, 0);
resolve();
}).then(function () {
console.log('异步1微任务then')
})
}, 0);
console.log('主线程宏任务');
setTimeout(() => {
console.log('异步2任务time2');
}, 0);
new Promise(function (resolve, reject) {
console.log('宏任务promise');
// reject();
resolve();
}).then(function () {
console.log('微任务then')
}).catch(function () {
console.log('微任务catch')
})
console.log('主线程宏任务2');
本例中需注意第9行的then是在第14行的setTimeout之前执行的,而第5行的setTimeout在第14行之后执行。也就是在一个异步任务代码块中,会先执行完所有同步语句(包括宏任务和微任务),然后去执行整个代码中的同级别的异步任务,而第5行的setTimeout因是第二层异步语句,会被放到之后才执行。
转载自:https://juejin.cn/post/6915731312527540238