返回

手写Promise,知其然,更知其所以然

前端

手写Promise,知其然,更知其所以然

作为一名合格的开发者,我们对Promise这个概念并不陌生,它是一个JavaScript原生对象,用于处理异步操作。Promise的出现,为我们带来了更加优雅的异步编程方式,也让我们的代码更加易读和易于维护。

然而,仅仅会使用Promise是不够的,我们还应该知道它是如何实现的,这样才能更好地理解它的工作原理,并将其应用到实际开发中。

手写Promise,可以帮助我们更好地理解Promise的实现机制。通过手写Promise,我们可以一步一步地了解Promise的内部工作原理,从而对Promise有更深入的理解。

为了手写Promise,我们需要先了解Promise的基本原理。Promise有三个状态:pending(等待)、fulfilled(已完成)和rejected(已拒绝)。pending状态表示Promise尚未完成,fulfilled状态表示Promise已成功完成,rejected状态表示Promise已失败。

Promise通过两个方法来改变其状态:resolve和reject。resolve方法用于将Promise的状态从pending变为fulfilled,reject方法用于将Promise的状态从pending变为rejected。

当Promise的状态改变时,它会通知所有已注册的回调函数。回调函数可以是then方法或catch方法。then方法用于处理Promise已完成的情况,catch方法用于处理Promise已失败的情况。

现在,我们已经了解了Promise的基本原理,接下来,我们就开始手写Promise。

首先,我们需要创建一个Promise对象。我们可以使用以下代码来创建Promise对象:

function Promise(executor) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  const resolve = (value) => {
    if (this.state !== 'pending') return;
    this.state = 'fulfilled';
    this.value = value;
    this.onFulfilledCallbacks.forEach((callback) => {
      callback(value);
    });
  };

  const reject = (reason) => {
    if (this.state !== 'pending') return;
    this.state = 'rejected';
    this.reason = reason;
    this.onRejectedCallbacks.forEach((callback) => {
      callback(reason);
    });
  };

  try {
    executor(resolve, reject);
  } catch (error) {
    reject(error);
  }
}

接下来,我们需要实现then方法和catch方法。then方法用于处理Promise已完成的情况,catch方法用于处理Promise已失败的情况。

Promise.prototype.then = function(onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    if (this.state === 'fulfilled') {
      setTimeout(() => {
        try {
          const value = onFulfilled(this.value);
          resolve(value);
        } catch (error) {
          reject(error);
        }
      }, 0);
    } else if (this.state === 'rejected') {
      setTimeout(() => {
        try {
          const reason = onRejected(this.reason);
          resolve(reason);
        } catch (error) {
          reject(error);
        }
      }, 0);
    } else {
      this.onFulfilledCallbacks.push(() => {
        setTimeout(() => {
          try {
            const value = onFulfilled(this.value);
            resolve(value);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });

      this.onRejectedCallbacks.push(() => {
        setTimeout(() => {
          try {
            const reason = onRejected(this.reason);
            resolve(reason);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });
    }
  });
};

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

最后,我们就可以使用我们的手写Promise对象了。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello world');
  }, 1000);
});

promise.then((value) => {
  console.log(value); // 'hello world'
});

通过手写Promise,我们不仅可以更好地理解Promise的实现机制,还可以锻炼我们的编程能力。如果你想成为一名合格的开发者,那么手写Promise是一个非常值得尝试的事情。