宏任务(macrotask)和微任务(microtask)的执行顺序
- 总体原则:JavaScript 是单线程语言,事件循环机制用于协调执行任务,分为宏任务队列和微任务队列。
- 宏任务队列包括:
script
(整体代码)、setTimeout
、setInterval
、setImmediate
(Node.js 环境)、I/O
、UI rendering
等。
- 微任务队列包括:
Promise.then
、process.nextTick
(Node.js 环境)、MutationObserver
等。
- 执行过程:
- 首先执行全局
script
作为第一个宏任务。
- 在执行宏任务过程中,会将产生的微任务添加到微任务队列。当宏任务执行完毕,会立即执行微任务队列中的所有任务,直到微任务队列为空。
- 然后从宏任务队列中取出下一个宏任务执行,重复上述过程,即每次宏任务执行完都清空微任务队列。
实际代码表现示例
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise.then');
});
console.log('end');
- 执行分析:
- 首先执行全局
script
宏任务,打印 start
。
- 遇到
setTimeout
,将其回调函数放入宏任务队列。
- 遇到
Promise.resolve().then
,将其回调函数放入微任务队列。
- 继续执行全局
script
,打印 end
。此时全局 script
宏任务执行完毕。
- 开始执行微任务队列,打印
Promise.then
,微任务队列清空。
- 从宏任务队列取出
setTimeout
的回调函数执行,打印 setTimeout
。
- 最终输出结果:
start
end
Promise.then
setTimeout