宏队列和微队列
JS中用来存储待执行回调函数的队列包含两个不同的特定的队列
-
宏队列:用来保存待执行的宏任务(回调),如:定时器回调、dom事件回调、ajax回调
-
微队列:用来保存待执行的微任务(回调),如:promise的回调、MutationServer的回调
- js首先必须执行完所有的初始化同步代码
- 每次准备取出第一个宏任务执行前,都要先将所有的微任务一个接一个地取出来执行
分析输出结果:
setTimeout(()=>{
console.log('0');
},0);
new Promise((resolve,reject)=>{
console.log('1');
resolve();
}).then(()=>{
console.log('2');
new Promise((resolve,reject)=>{
console.log('3');
resolve();
}).then(()=>{
console.log('4');
}).then(()=>{
console.log('5');
})
}).then(()=>{
console.log('6');
})
new Promise((resolve,reject)=>{
console.log('7');
resolve();
}).then(()=>{
console.log('8');
})
先看同步,再看回调
- 开头一个定时器,将0压入宏队列
- new Promise中executor同步执行,直接输出1
- 接着执行rresolve(),状态改变,调用then(),将成功回调函数压入微队列(2)
- 由于输出2这里还没执行,可以先不管其下的new Promise,此时第一个then()还没执行结束因此第二个then()也还没开始执行
- 然后执行下一个new Promise,直接将7输出,然后立马执行resolve(),改变状态后将then()里面成功的回调压入微队列(8)
- 此时初始化代码全部执行完毕
输出:1 7
宏队列:[0]
微队列:[2,8]
执行微队列中的回调
- 输出2,console.log(‘2’);执行完后new Promise,直接输出3,立马执行resolve()改变状态后then()成功回调压入微队列(4)。由于此时4还未执行,因此其后输出5的回调不能压入微队列,而是放入缓存,由于状态改变,其后的then()已经执行完了,因此将外层下一个then的回调压入微队列(6)
输出:1 7 2 3
宏队列:[0]
微队列:[8,4,6]
执行输出8,此步不影响其他操作,接着输出4,将其后的回调压入微队列(5)
输出:1 7 2 3 8 4
宏队列:[0]
微队列:[6,5]
最后就是:
输出:1 7 2 3 8 4 6 5 0
宏队列:[]
微队列:[]