宏任务和微任务
前端小伙伴面试的时候,一定遇到过promise和计时器 输出值、执行先后顺序的题目。下面给大家梳理下具体知识点。
宏任务和微任务
宏任务包括:
script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)
微任务包括:
Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)
执行顺序
通俗讲:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
示例分析(我看了好多宏任务微任务的技术帖,示例1几乎都有)
示例1
setTimeout(function(){ console.log('1'); }); new Promise(function(resolve){ console.log('2'); resolve(); }).then(function(){ console.log('3'); }); console.log('4');
- 遇到setTimout,异步宏任务,放入宏任务队列中;
- 遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2;
- 而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
- 遇到同步任务console.log(‘4’);输出4;主线程中同步任务执行完
- 从微任务队列中取出任务到主线程中,输出3,微任务队列为空
- 从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空,结束
//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
//微事件1
process.nextTick(function() {
console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
//微事件2
console.log('8')
})
//丢到宏事件队列中
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
- 首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log('1')
- 遇到 setTimeout 分发到宏任务Event Queue中
- 遇到 process.nextTick 丢到微任务Event Queue中
- 遇到 Promise, new Promise 直接执行 输出 console.log('7');
- 执行then 被分发到微任务Event Queue中
- 第一轮宏任务执行结束,开始执行微任务 打印 6,8
- 第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout
- 先执行主线程宏任务,在执行微任务,打印'2,4,3,5'
- 在执行第二个setTimeout,同理打印 ‘9,11,10,12’
- 整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。
以上是自己综合总结大佬们技术帖糅合成的文章,谢谢查看。

浙公网安备 33010602011771号