返回

亲自动手,写一个Promise

前端

前言

在现代JavaScript开发中,Promise是一种必不可少的工具。它使我们能够轻松处理异步操作,并避免回调地狱。Promise具有许多优点,包括:

  • 易于使用:Promise的API非常简单,易于理解和使用。
  • 可读性强:Promise的代码非常可读,易于理解和维护。
  • 可组合性:Promise可以很容易地组合在一起,以创建复杂的异步操作。
  • 错误处理:Promise提供了内置的错误处理机制,使我们可以轻松地处理异步操作中的错误。

Promise的特点

Promise具有以下几个特点:

  • 状态:Promise有三个状态:pending(等待)、fulfilled(已完成)和rejected(已拒绝)。
  • 回调函数:Promise有两个回调函数:resolve和reject。resolve用于将Promise的状态更改为fulfilled,reject用于将Promise的状态更改为rejected。
  • then方法:Promise的then方法用于处理Promise的状态变化。当Promise的状态变为fulfilled时,then方法的第一个参数将被调用;当Promise的状态变为rejected时,then方法的第二个参数将被调用。
  • catch方法:Promise的catch方法用于处理Promise的错误。当Promise的状态变为rejected时,catch方法将被调用。

Promise的实现

我们现在从零开始实现一个Promise。首先,我们定义一个Promise类:

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

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

  resolve(value) {
    if (this.state !== 'pending') {
      return;
    }

    this.state = 'fulfilled';
    this.value = value;

    this.onFulfilledCallbacks.forEach(callback => {
      callback(value);
    });
  }

  reject(reason) {
    if (this.state !== 'pending') {
      return;
    }

    this.state = 'rejected';
    this.reason = reason;

    this.onRejectedCallbacks.forEach(callback => {
      callback(reason);
    });
  }

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

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

  catch(onRejected) {
    return this.then(null, onRejected);
  }
}

这个Promise类的实现非常简单。它包含了一个构造函数,用于创建一个新的Promise实例。构造函数接受一个executor函数作为参数。executor函数有两个参数:resolve和reject。resolve用于将Promise的状态更改为fulfilled,reject用于将Promise的状态更改为rejected。

Promise类还包含四个方法:resolve、reject、then和catch。resolve方法用于将Promise的状态更改为fulfilled,reject方法用于将Promise的状态更改为rejected,then方法用于处理Promise的状态变化,catch方法用于处理Promise的错误。

Promise的使用

我们现在来看一下如何使用Promise。首先,我们创建一个Promise实例:

const promise = new Promise((resolve, reject) => {
  // 异步操作
});

然后,我们可以使用then方法来处理Promise的状态变化:

promise.then(value => {
  // Promise的状态变为fulfilled时执行的代码
}, reason => {
  // Promise的状态变为rejected时执行的代码
});

如果我们想处理Promise的错误,我们可以使用catch方法:

promise.catch(reason => {
  // Promise的状态变为rejected时执行的代码
});

结语

Promise是一种非常强大的工具,可以帮助我们轻松处理异步操作。它易于使用、可读性强、可组合性强,并提供了内置的错误处理机制。如果您还没有使用过Promise,我强烈建议您学习并使用它。