返回

JavaScript 的宏任务和微任务,你真的搞懂了吗?

前端

理解 JavaScript 的宏任务和微任务:掌握异步编程的关键

在 JavaScript 中,宏任务和微任务是异步编程的关键概念,可以帮助我们在主线程空闲时执行任务。掌握它们之间的差异对于理解 JavaScript 异步编程至关重要,也是面试中经常遇到的问题。

宏任务与微任务

  • 宏任务: 指那些需要花费较长时间才能完成的任务,例如 setTimeout()、setInterval()、script 标签和 DOM 操作。宏任务会先执行,然后是微任务。
  • 微任务: 指那些需要花费很短时间就能完成的任务,例如 Promise.then()、MutationObserverXMLHttpRequest。微任务会先执行,然后是宏任务。

Event Loop

JavaScript 中有一个称为 Event Loop 的循环,它负责执行任务队列中的任务。Event Loop 先执行微任务队列中的任务,再执行宏任务队列中的任务。如果在执行宏任务的过程中又产生了新的微任务,这些微任务会先执行,然后再继续执行宏任务。

两行代码的迷惑现象

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

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

这段代码中,setTimeout() 是一个宏任务,Promise.resolve().then() 是一个微任务。按照 Event Loop 的执行顺序,微任务会先执行,所以 B 会先输出。但是,如果我们将 setTimeout() 改成 setImmediate(),那么 A 就会先输出。这是因为 setImmediate() 是一个微任务,它会比 setTimeout() 先执行。

让宏任务先执行

如果我们希望让 A 先输出,可以使用 process.nextTick()

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

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

process.nextTick(() => {
  console.log('A');
});

process.nextTick() 是一个微任务,它会比 Promise.resolve().then() 先执行,所以 A 会先输出。

结语

宏任务和微任务是 JavaScript 异步编程中的重要概念。理解它们之间的差异对于避免奇怪的问题和编写可靠的代码至关重要。在面试中,宏任务和微任务也经常会被问到,掌握这些知识可以帮助你轻松应对。

常见问题解答

  1. 宏任务和微任务的区别是什么?
    宏任务需要较长时间才能完成,而微任务则需要很短的时间。宏任务先执行,然后是微任务。
  2. Event Loop 如何执行任务?
    Event Loop 先执行微任务队列中的任务,再执行宏任务队列中的任务。
  3. 如何让宏任务先执行?
    可以使用 process.nextTick()
  4. setImmediate() 是一个宏任务还是微任务?
    setImmediate() 是一个微任务。
  5. 为什么在面试中经常会被问到宏任务和微任务?
    因为它们是 JavaScript 异步编程的关键概念,理解它们对于编写可靠的代码至关重要。