HLJ 发布于
2025-06-11 11:04:05
0阅读

JavaScript Promise 微任务机制解析

JavaScript Promise 微任务(Microtask)

在 JavaScript 中,Promise 的回调是通过微任务队列(Microtask Queue)来处理的,这与常规的异步任务(如 setTimeout、setInterval 等)使用的宏任务队列(Macrotask Queue/Task Queue)不同。

微任务 vs 宏任务

  • 微任务(Microtask)

    • Promise 的 .then().catch().finally() 回调
    • MutationObserver
    • process.nextTick(Node.js 环境)
    • queueMicrotask API
  • 宏任务(Macrotask)

    • setTimeout、setInterval
    • setImmediate(Node.js 环境)
    • I/O 操作
    • UI 渲染
    • 事件回调(如 click 事件)

执行顺序

JavaScript 事件循环(Event Loop)的执行顺序规则:

  1. 执行当前同步代码
  2. 执行当前微任务队列中的所有任务(直到队列为空)
  3. 如有必要进行渲染,执行渲染
  4. 从宏任务队列中取出一个任务执行
  5. 重复上述过程

示例代码

console.log('Script start');

setTimeout(() => {
  console.log('setTimeout');
}, 0);

Promise.resolve()
  .then(() => {
    console.log('Promise 1');
  })
  .then(() => {
    console.log('Promise 2');
  });

console.log('Script end');

输出顺序:

Script start
Script end
Promise 1
Promise 2
setTimeout

微任务嵌套

微任务会在当前事件循环中全部执行完毕,即使是在微任务中产生的新的微任务:

Promise.resolve()
  .then(() => {
    console.log('Promise 1');
    return Promise.resolve();
  })
  .then(() => {
    console.log('Promise 2');
    queueMicrotask(() => {
      console.log('queueMicrotask');
    });
  })
  .then(() => {
    console.log('Promise 3');
  });

输出顺序:

Promise 1
Promise 2
queueMicrotask
Promise 3

实际应用

理解微任务对于控制代码执行顺序非常重要,特别是在处理异步操作时:

let button = document.getElementById('button');
button.addEventListener('click', () => {
  Promise.resolve().then(() => console.log('Microtask 1'));
  console.log('Listener 1');
});

button.addEventListener('click', () => {
  Promise.resolve().then(() => console.log('Microtask 2'));
  console.log('Listener 2');
});

button.click();

输出顺序:

Listener 1
Listener 2
Microtask 1
Microtask 2

注意事项

  1. 微任务队列会在当前宏任务执行完毕后立即执行
  2. 如果在微任务中创建新的微任务,它们会在当前事件循环中全部执行完毕
  3. 过多的微任务可能导致页面响应变慢(称为"微任务饥饿")
  4. 使用 queueMicrotask() 可以直接将函数加入微任务队列

理解微任务机制对于编写高效、可预测的异步 JavaScript 代码至关重要。

当前文章内容为原创转载请注明出处:http://www.good1230.com/detail/2025-06-11/834.html
最后生成于 2025-06-13 20:53:48
此内容有帮助 ?
0