返回

解剖Promise:掌握核心概念,亲自动手实现

前端

Promises是我们JavaScript工具箱中强大而有用的工具,它可以解决异步编程中许多棘手的问题。不过,了解Promise的内部原理同样重要。本文将带你走近Promise的底层,并提供一个手动实现Promise的示例,帮助你更深入地理解这种语言特性。

Promise的几个核心概念:

  • 状态: 每个Promise都有一个状态,可以是Pending(进行中)、Fulfilled(已完成)或Rejected(已拒绝)。
  • 值: Fulfilled的Promise带有值,而Rejected的Promise带有错误原因。
  • 处理程序: Promise可以添加处理程序,当Promise的状态改变时,这些处理程序会被调用。

手动实现Promise的步骤:

  1. 创建Promise构造函数:
function Promise(executor) {
  // 状态变量,初始为Pending
  this.state = 'pending';
  // 值或错误原因
  this.value = undefined;
  // 处理程序队列
  this.handlers = [];

  // 执行器函数
  // executor(resolve, reject)
  // resolve(value)用于将Promise的状态从Pending变为Fulfilled并设置值
  // reject(reason)用于将Promise的状态从Pending变为Rejected并设置错误原因
  try {
    executor(resolve.bind(this), reject.bind(this));
  } catch (err) {
    reject(err);
  }
}
  1. 添加处理程序:
Promise.prototype.then = function(onFulfilled, onRejected) {
  // 处理程序回调函数
  const handler = {
    onFulfilled: typeof onFulfilled === 'function' ? onFulfilled : null,
    onRejected: typeof onRejected === 'function' ? onRejected : null
  };

  // 将处理程序推入队列
  this.handlers.push(handler);

  // 如果Promise已经完成,立即调用处理程序
  if (this.state !== 'pending') {
    this.executeHandlers();
  }
};
  1. 执行处理程序:
Promise.prototype.executeHandlers = function() {
  while (this.handlers.length > 0) {
    const handler = this.handlers.shift();

    // 根据Promise的状态调用相应的处理程序
    if (this.state === 'fulfilled') {
      if (handler.onFulfilled) {
        handler.onFulfilled(this.value);
      }
    } else if (this.state === 'rejected') {
      if (handler.onRejected) {
        handler.onRejected(this.value);
      }
    }
  }
};
  1. 解析或拒绝Promise:
function resolve(value) {
  // 将状态从Pending改为Fulfilled
  this.state = 'fulfilled';
  // 设置值
  this.value = value;
  // 执行处理程序
  this.executeHandlers();
}

function reject(reason) {
  // 将状态从Pending改为Rejected
  this.state = 'rejected';
  // 设置错误原因
  this.value = reason;
  // 执行处理程序
  this.executeHandlers();
}

通过遵循这些步骤,你可以手动实现一个功能齐全的Promise。这种练习有助于你更好地理解Promise的底层工作原理,从而提高你的JavaScript编程能力。