面试题答案
一键面试- 宏任务(macrotask)常见任务类型:
setTimeout
setInterval
setImmediate
(仅在 Node.js 环境中有)- I/O 操作(在 Node.js 中)
- 浏览器中的
requestAnimationFrame
(虽然严格意义不完全等同于宏任务,但执行时机类似)
- 微任务(microtask)常见任务类型:
Promise
的then
回调MutationObserver
(用于监听 DOM 变化,在浏览器环境中)process.nextTick
(仅在 Node.js 环境中有,它的优先级比微任务队列中其他任务更高)
- 执行顺序:
- 事件循环开始时,先执行宏任务队列中的第一个任务(初始脚本也作为第一个宏任务)。
- 执行宏任务过程中,会将产生的微任务添加到微任务队列。
- 宏任务执行完后,会清空微任务队列,依次执行微任务队列中的所有任务。
- 微任务队列清空后,再从宏任务队列中取出下一个宏任务执行,如此循环。
- 对于给定代码的输出结果:
- 首先,初始脚本作为宏任务开始执行,输出
script start
。 - 遇到
setTimeout
,它是宏任务,被放到宏任务队列中,此时不执行。 - 遇到
Promise.resolve().then
,then
回调是微任务,被放到微任务队列中。 - 继续执行脚本,输出
script end
,初始脚本(宏任务)执行完毕。 - 开始清空微任务队列,执行
Promise
的then
回调,输出promise1
,then
回调又产生了一个新的then
回调,也是微任务,添加到微任务队列,继续清空微任务队列,执行新添加的then
回调,输出promise2
,微任务队列清空。 - 从宏任务队列中取出
setTimeout
任务执行,输出setTimeout
。
- 首先,初始脚本作为宏任务开始执行,输出
所以最终输出结果为:
script start
script end
promise1
promise2
setTimeout