宏任务与微任务 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第2天
同步任务与异步任务
- JS分为同步任务和异步任务
- 同步任务在主线程上执行,形成执行栈
- 异步任务运行会先放到任务队列中
- 当执行栈中的任务执行完毕时,系统会去读取任务队列中的任务,将其添加到执行栈中去执行
- 如此往复也称事件循环
宏任务与微任务
宏任务包含:
- script (可以理解为外层同步代码)
- setTimeout
- setInterval
- UI交互事件
- postMessage
- MessageChannel
- setImmediate(node环境)
微任无包含:
- Promise.then
- Object.observe
- process.nextTick(node环境)
- MutationObserver
宏任务和微任务执行顺序
- 执行宏任务,碰到微任务就将其放入微任务队列中
- 宏任务执行完毕后,立即执行微任务队列中的微任务
- 浏览器渲染
- 开始下一个宏任务
例题
console.log(1)
setTimeout(()=>{
new Promise(resolve=>{
resolve()
}).then(()=>{
console.log(2)
})
console.log(3)
})
new Promise(resolve=>{
resolve()
console.log(4)
}).then(()=>{
console.log(5)
Promise.resolve().then(()=>{
console.log(6)
}).then(()=>{
Promise.resolve().then(()=>{
console.log(7)
})
})
})
console.log(8)
// 1 4 8 5 6 7 3 2
console.log(1)
遇到setTimeout,将其放入宏任务队列
遇到Promise,执行console.log(4),将.then(console.log(5)...)放入微任务队列
console.log(8)
从微任务中取出.then(console.log(5)...),执行console.log(5)
将.then(console.log(6)...)放入微任务队列
将.then(()=>{Promis...})放入微任务队列
从微任务队列中取出.then(console.log(6)...),执行console.log(6)
从微任务队列中取出.then(()=>{Promis...}),将.then(console.log(7)...)放入微任务队列
从微任务队列中取出.then(console.log(7)...),执行console.log(7),微任务队列为空
从宏任务队列中取出任务(setTimeout),将.then(console.log(2))放入微任务队列
执行console.log(3)
从微任务队列中取出.then(console.log(2)...),执行console.log(2)