返回

基于手写了解 Promise 的本质

前端

前言

Promise 是 JavaScript 中用于处理异步操作和错误处理的强大工具。它提供了一种简单而优雅的方式来管理异步操作,使代码更易于阅读和维护。在本文中,我们将通过手写一个基础版本的 Promise,来帮助您从底层了解 Promise 的本质和使用方法。我们将涵盖 Promise 的常用方法,如 then()、all()、race()、resolve()、reject() 等,并通过示例代码演示如何使用它们来处理异步操作和错误处理。

Promise 的基本概念

Promise 是一个对象,它表示一个异步操作的最终完成或失败的结果。Promise 可以处于三种状态:

  • fulfilled :异步操作成功完成。
  • rejected :异步操作失败。
  • pending :异步操作仍在进行中。

Promise 的基本方法

Promise 提供了几个基本方法来处理异步操作和错误处理。这些方法包括:

  • then() :用于注册回调函数,以便在 Promise 完成或失败时执行。
  • all() :用于等待多个 Promise 同时完成。
  • race() :用于等待第一个完成的 Promise。
  • resolve() :用于将 Promise 的状态设置为 fulfilled。
  • reject() :用于将 Promise 的状态设置为 rejected。

手写一个基础版本的 Promise

为了更好地理解 Promise 的工作原理,我们现在将手写一个基础版本的 Promise。我们的 Promise 实现将包括 then() 和 resolve() 方法。

// 定义 Promise 类
class Promise {
  constructor(executor) {
    this.state = "pending";
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    // 执行器函数
    executor(resolve, reject) {
      // 将 resolve 和 reject 函数存储起来,以便在需要时调用
      this.resolve = resolve;
      this.reject = reject;
    }
  }

  // then 方法
  then(onFulfilled, onRejected) {
    // 如果 onFulfilled 不是函数,则将其设置为默认函数
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;

    // 如果 onRejected 不是函数,则将其设置为默认函数
    onRejected = typeof onRejected === "function" ? onRejected : (reason) => {
      throw reason;
    };

    // 根据 Promise 的状态,将回调函数添加到相应的数组中
    if (this.state === "fulfilled") {
      setTimeout(() => {
        onFulfilled(this.value);
      }, 0);
    } else if (this.state === "rejected") {
      setTimeout(() => {
        onRejected(this.reason);
      }, 0);
    } else {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    }

    // 返回一个新的 Promise 对象
    return new Promise((resolve, reject) => {
      // 在 then 方法中返回一个新的 Promise 对象,以便可以继续链式调用
      this.then(
        (value) => {
          // 如果 onFulfilled 函数执行成功,则调用 resolve() 函数,将新的 Promise 的状态设置为 fulfilled
          resolve(onFulfilled(value));
        },
        (reason) => {
          // 如果 onRejected 函数执行成功,则调用 reject() 函数,将新的 Promise 的状态设置为 rejected
          reject(onRejected(reason));
        }
      );
    });
  }

  // resolve 方法
  resolve(value) {
    // 将 Promise 的状态设置为 fulfilled
    this.state = "fulfilled";

    // 将 Promise 的值设置为给定的值
    this.value = value;

    // 依次执行所有 onFulfilled 回调函数
    this.onFulfilledCallbacks.forEach((callback) => {
      callback(this.value);
    });
  }

  // reject 方法
  reject(reason) {
    // 将 Promise 的状态设置为 rejected
    this.state = "rejected";

    // 将 Promise 的原因设置为给定的原因
    this.reason = reason;

    // 依次执行所有 onRejected 回调函数
    this.onRejectedCallbacks.forEach((callback) => {
      callback(this.reason);
    });
  }
}

使用示例

现在,我们已经手写了一个基础版本的 Promise,我们可以通过一些示例代码来演示如何使用它来处理异步操作和错误处理。

// 示例 1:使用 Promise 处理异步操作

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Hello, world!");
  }, 2000);
});

promise
  .then((value) => {
    console.log(value); // 输出:Hello, world!
  })
  .catch((reason) => {
    console.error(reason); // 不会被调用
  });

// 示例 2:使用 Promise 处理错误

const promise = new Promise((resolve, reject) => {
  throw new Error("Oops, something went wrong!");
});

promise
  .then((value) => {
    console.log(value); // 不会被调用
  })
  .catch((reason) => {
    console.error(reason); // 输出:Error: Oops, something went wrong!
  });

总结

通过本文,我们手写了一个基础版本的 Promise,并通过示例代码演示了如何使用它来处理异步操作和错误处理。希望这些内容能够帮助您更好地理解 Promise 的工作原理和使用方法。在实际开发中,您可以使用 JavaScript 语言内置的 Promise 对象,它提供了更丰富的功能和更强大的语法支持。