在js中,任务分为微任务(microtask)和宏任务(macrotask)是事件循环(event loop)的一部分,用于处理异步代码的执行。
宏任务(Macrotasks)
宏任务是指执行栈中按照顺序等待执行的任务。宏任务队列是先进先出的,即排在队列前面的宏任务会优先执行。常见的宏任务包括:
- script(整体代码)
- setTimeout
- setInterval
- setImmediate(Node.js环境)
- I/O 操作
- UI 渲染(浏览器环境)
微任务(Microtasks)
微任务通常在宏任务执行完毕后立即执行,微任务队列是后进先出的,也就是说微任务队列中的任务会按照“后进先出”的顺序执行。这样设计是为了确保微任务尽快执行,而不需要等待其他宏任务。常见的微任务包括:
- Promise 的回调(.then(), .catch(), .finally())
- process.nextTick(Node.js环境)
- Object.observe(已废弃)
- MutationObserver(监听DOM变化)
执行顺序
在JavaScript的事件循环中,微任务和宏任务的执行顺序如下:
- 执行栈为空时,首先检查微任务队列是否为空。
- 如果微任务队列不为空,则执行微任务队列中的所有任务,直到微任务队列为空。
- 如果微任务队列为空,则执行宏任务队列中的一个任务。
- 执行完一个宏任务后,回到第1步。
这个循环过程就是事件循环,确保了JavaScript的非阻塞异步行为。
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
script start
script end
promise1
promise2
setTimeout
在这个例子中,script start 和 script end 首先打印,因为它们是同步代码。然后,JavaScript引擎会处理微任务队列中的Promise回调,打印promise1和promise2。最后,执行宏任务队列中的setTimeout,打印setTimeout。