返回

Promise 基础版本的实现原理

前端

Promise 基础版本实现

Promise 构造函数

function MyPromise(executor) {
  if (typeof executor !== 'function') {
    throw new TypeError('Executor must be a function');
  }
  this.status = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];
  try {
    executor(resolve.bind(this), reject.bind(this));
  } catch (e) {
    reject.call(this, e);
  }
}

在构造函数内部,我们定义了 Promise 的初始状态为「pending」,并设置了「value」和「reason」两个属性来分别保存最终的结果和错误信息。另外,我们还定义了两个回调函数数组「onFulfilledCallbacks」和「onRejectedCallbacks」来分别保存「resolve」和「reject」的回调函数。

在构造函数中,我们传入一个「executor」函数,该函数接收两个参数「resolve」和「reject」。「resolve」和「reject」是两个用于改变 Promise 状态的函数,我们将在下面介绍它们的使用。

resolve 和 reject 函数

function resolve(value) {
  if (this.status !== 'pending') return;
  this.status = 'fulfilled';
  this.value = value;
  this.onFulfilledCallbacks.forEach(callback => callback(this.value));
}
function reject(reason) {
  if (this.status !== 'pending') return;
  this.status = 'rejected';
  this.reason = reason;
  this.onRejectedCallbacks.forEach(callback => callback(this.reason));
}

「resolve」函数用于将 Promise 的状态从「pending」变为「fulfilled」,并传入一个结果值。「reject」函数用于将 Promise 的状态从「pending」变为「rejected」,并传入一个错误原因。

当「resolve」或「reject」函数被调用时,它们会将 Promise 的状态修改为「fulfilled」或「rejected」,并根据状态来调用相应的回调函数数组中的所有回调函数。

then 方法

MyPromise.prototype.then = function (onFulfilled, onRejected) {
  return new MyPromise((resolve, reject) => {
    const resolvePromise = (value) => {
      if (typeof onFulfilled === 'function') {
        try {
          const x = onFulfilled(value);
          resolve(x);
        } catch (e) {
          reject(e);
        }
      } else {
        resolve(value);
      }
    };
    const rejectPromise = (reason) => {
      if (typeof onRejected === 'function') {
        try {
          const x = onRejected(reason);
          resolve(x);
        } catch (e) {
          reject(e);
        }
      } else {
        reject(reason);
      }
    };
    if (this.status === 'pending') {
      this.onFulfilledCallbacks.push(resolvePromise);
      this.onRejectedCallbacks.push(rejectPromise);
    } else if (this.status === 'fulfilled') {
      setTimeout(() => resolvePromise(this.value), 0);
    } else {
      setTimeout(() => rejectPromise(this.reason), 0);
    }
  });
};

「then」方法用于为 Promise 添加回调函数,以便在 Promise 状态发生变化时执行。它接收两个参数「onFulfilled」和「onRejected」,分别用于处理「fulfilled」和「rejected」状态。

在「then」方法中,我们返回了一个新的 Promise 实例,以便能够链式调用。同时,我们会将「resolvePromise」和「rejectPromise」函数分别推入「onFulfilledCallbacks」和「onRejectedCallbacks」数组中。

当 Promise 状态变为「fulfilled」或「rejected」时,我们会调用相应的回调函数数组中的所有回调函数。为了确保回调函数是在主事件循环中执行的,我们使用「setTimeout」函数来延迟执行回调函数。