返回

手写 Promise 实现工作流

前端

Promise 简介

Promise 是 JavaScript 中用来处理异步编程的一种对象。它代表一个异步操作的最终完成或失败的结果。Promise 对象有三个状态:

  • Pending: 初始状态,表示异步操作尚未完成。
  • Fulfilled: 成功状态,表示异步操作已成功完成。
  • Rejected: 失败状态,表示异步操作已失败。

手写 Promise

我们可以使用 ES6 中的 class 来手写 Promise。首先,我们需要定义一个 Promise 的构造函数:

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

    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
}
  • executor 是一个函数,它接受两个参数:resolverejectresolve 用来将 Promise 的状态变为 fulfilledreject 用来将 Promise 的状态变为 rejected
  • state 属性表示 Promise 的状态,可以是 pendingfulfilledrejected
  • value 属性表示 Promise 成功完成后的结果值。
  • reason 属性表示 Promise 失败后的原因。
  • onFulfilledCallbacksonRejectedCallbacks 分别是用于存储 fulfilledrejected 回调函数的数组。

接下来,我们需要定义 resolvereject 方法:

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));
}
  • resolve 方法将 Promise 的状态变为 fulfilled,并执行所有 onFulfilledCallbacks 回调函数。
  • reject 方法将 Promise 的状态变为 rejected,并执行所有 onRejectedCallbacks 回调函数。

最后,我们需要定义 then 方法:

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

      this.onRejectedCallbacks.push(() => {
        onRejected(this.reason);
      });
    }
  });
}
  • then 方法返回一个新的 Promise,该 Promise 的状态取决于当前 Promise 的状态。
  • 如果当前 Promise 的状态是 fulfilled,则执行 onFulfilled 回调函数,并以 onFulfilled 回调函数的返回值作为新 Promise 的结果值。
  • 如果当前 Promise 的状态是 rejected,则执行 onRejected 回调函数,并以 onRejected 回调函数的返回值作为新 Promise 的失败原因。
  • 如果当前 Promise 的状态是 pending,则将 onFulfilledonRejected 回调函数分别添加到 onFulfilledCallbacksonRejectedCallbacks 数组中,等待当前 Promise 的状态改变。

手写 Promise 的应用场景

手写 Promise 可以用于处理各种异步编程场景,例如:

  • Ajax 请求
  • 定时器
  • 事件监听器
  • WebSockets

手写 Promise 的注意事项

在使用手写 Promise 时,需要注意以下几点:

  • 手写 Promise 是一种相对低级的 API,使用时需要非常小心。
  • 手写 Promise 容易出错,建议使用原生 Promise 或其他 Promise 库。
  • 手写 Promise 可以帮助我们更好地理解 Promise 的工作原理,但并不建议在生产环境中使用。

结语

手写 Promise 是一种相对低级的 API,使用时需要非常小心。建议使用原生 Promise 或其他 Promise 库。但学习如何手写 Promise 可以帮助我们更好地理解 Promise 的工作原理。