返回

Promise 原理剖析:揭秘 EventLoop 的秘密

前端

引言

在上一篇文章中,我们深入探讨了 Promise 的使用方法,了解了其在异步编程中的强大功能。本次,我们将踏入更深层次的旅程,揭开 Promise 的原理面纱,探索 EventLoop 在其背后的神奇运作。

Promise 的状态改变

Promise 有三种状态:等待(pending)、已完成(fulfilled)和已拒绝(rejected)。状态只能被改变一次。当一个 Promise 被创建时,它处于等待状态。当异步操作完成时,Promise 的状态就会被修改为已完成或已拒绝。

EventLoop

EventLoop 是 JavaScript 运行时的核心机制。它的职责是监听事件队列,并在其中有事件时依次执行它们。事件队列由微任务队列和宏任务队列组成。

微任务

微任务是在当前执行栈执行完毕后立即执行的函数。它们优先于宏任务执行。当 Promise 的异步操作完成时,它会将一个微任务推入微任务队列。这个微任务将在下一个执行周期中执行,从而修改 Promise 的状态。

宏任务

宏任务是在本轮事件循环结束、所有微任务执行完毕后才执行的函数。它们包括 setTimeout()、setInterval()、UI 渲染等。当一个宏任务被执行时,它会将自身从事件队列中移除。

Promise 原理

当一个 Promise 被创建时,它会在微任务队列中注册一个微任务。当异步操作完成时,微任务会被执行,从而修改 Promise 的状态。如果 Promise 的状态被修改为已完成,则将调用它的 then() 方法;如果状态被修改为已拒绝,则将调用它的 catch() 方法。

示例

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功!");
  }, 1000);
});

promise
  .then((result) => {
    console.log(result); // 输出: "成功!"
  })
  .catch((error) => {
    console.log(error); // 不会被执行
  });

在这个示例中,Promise 的异步操作(setTimeout)完成后,会将一个微任务推入微任务队列。这个微任务会在当前执行栈执行完毕后执行,从而修改 Promise 的状态为已完成。随后,then() 方法中的回调函数将被调用,输出 "成功!"。

总结

Promise 的原理依赖于 EventLoop 的运作机制。微任务优先于宏任务执行,当 Promise 的异步操作完成时,它会将一个微任务推入微任务队列。这个微任务会在下一个执行周期中执行,从而修改 Promise 的状态并触发 then() 或 catch() 方法的执行。掌握这些原理至关重要,因为它能帮助我们更好地理解和使用 Promise。