返回

揭秘JavaScript Promise的神秘面纱:亲手编写实现,一探究竟

前端

作为一名JavaScript开发人员,我们每天都在与异步编程打交道,Promise是JavaScript中用来处理异步操作的强大工具。它提供了更优雅、更清晰的方式来处理异步代码,让我们能够以同步的方式编写异步代码。

然而,仅仅知道如何使用Promise并不能完全理解它的内部运作机制。为了更好地掌握Promise,我们需要深入了解它的实现细节。

因此,在这篇文章中,我们将通过亲手编写一个简单的Promise实现——myPromise——来揭开Promise的神秘面纱,深入探索它的内部世界。

一、Promise的基本原理

Promise本质上是一个对象,它表示一个异步操作的最终完成或失败的状态。它提供了两个主要方法:then和catch。then方法用于处理异步操作成功完成时的情况,而catch方法用于处理异步操作失败时的情况。

二、实现myPromise

为了实现myPromise,我们需要模拟Promise的基本原理。首先,我们需要创建一个构造函数MyPromise。

function MyPromise(executor) {
  // 初始化状态为pending
  this.status = 'pending';
  // 存储成功的值
  this.value = undefined;
  // 存储失败的原因
  this.reason = undefined;
  // then方法的回调函数队列
  this.onFulfilledCallbacks = [];
  // catch方法的回调函数队列
  this.onRejectedCallbacks = [];

  // 执行器函数
  executor(resolve, reject);

  function resolve(value) {
    // 将状态改为resolved
    this.status = 'resolved';
    // 将成功的值存储起来
    this.value = value;
    // 依次执行then方法的回调函数
    this.onFulfilledCallbacks.forEach(callback => callback(value));
  }

  function reject(reason) {
    // 将状态改为rejected
    this.status = 'rejected';
    // 将失败的原因存储起来
    this.reason = reason;
    // 依次执行catch方法的回调函数
    this.onRejectedCallbacks.forEach(callback => callback(reason));
  }
}

三、then方法的实现

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  // 如果onFulfilled不是函数,则忽略它
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  // 如果onRejected不是函数,则忽略它
  onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };

  // 返回一个新的Promise对象
  return new MyPromise((resolve, reject) => {
    // 如果状态为pending,则将回调函数存储起来
    if (this.status === 'pending') {
      this.onFulfilledCallbacks.push(() => {
        // 调用onFulfilled并获取返回值
        const value = onFulfilled(this.value);
        // 将返回值作为新Promise对象的resolve的参数
        resolve(value);
      });

      this.onRejectedCallbacks.push(() => {
        // 调用onRejected并获取返回值
        const reason = onRejected(this.reason);
        // 将返回值作为新Promise对象的reject的参数
        reject(reason);
      });
    }

    // 如果状态为resolved,则直接调用onFulfilled
    else if (this.status === 'resolved') {
      setTimeout(() => {
        const value = onFulfilled(this.value);
        resolve(value);
      });
    }

    // 如果状态为rejected,则直接调用onRejected
    else if (this.status === 'rejected') {
      setTimeout(() => {
        const reason = onRejected(this.reason);
        reject(reason);
      });
    }
  });
};

四、catch方法的实现

MyPromise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected);
};

五、使用myPromise

现在,我们已经实现了myPromise,接下来让我们看看如何使用它。

const myPromise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功!');
  }, 1000);
});

myPromise.then(value => {
  console.log(value); // 输出:成功!
});

六、结语

通过亲手编写一个简单的myPromise对象,我们深入了解了Promise的内部运作机制。我们看到,Promise本质上是一个对象,它包含了状态、值、原因以及then和catch方法。通过理解这些细节,我们能够更好地掌握Promise的使用,并编写出更加健壮的异步代码。