返回

剖析 Promise(1) - 手写 Promise 深度解析

前端

在 JavaScript 中,我们经常会遇到异步编程,即代码的执行顺序与代码的书写顺序不一致。为了解决异步编程中常见的回调地狱问题,Promise 应运而生。

Promise 是一个对象,它表示一个异步操作的最终完成或失败的状态。它提供了 then() 方法,允许我们在异步操作完成后执行回调函数。

1. Promise 的创建

const promise = new Promise((resolve, reject) => {
  // 异步操作代码
  if (success) {
    resolve(result);
  } else {
    reject(error);
  }
});

Promise 构造函数接受一个函数作为参数,这个函数有两个参数:resolve 和 reject。这两个函数都是 Promise 提供给用户的方法,可以更改 Promise 的状态。

如果异步操作成功,则调用 resolve() 方法,并将结果作为参数传递给它。如果异步操作失败,则调用 reject() 方法,并将错误作为参数传递给它。

2. Promise 的状态

Promise 有三种状态:pending、fulfilled 和 rejected。

  • pending:表示 Promise 尚未完成。
  • fulfilled:表示 Promise 已成功完成。
  • rejected:表示 Promise 已失败。

3. Promise 的 then() 方法

Promise 的 then() 方法允许我们在异步操作完成后执行回调函数。它的语法如下:

promise.then(onFulfilled, onRejected);
  • onFulfilled:当 Promise 完成时执行的回调函数。
  • onRejected:当 Promise 失败时执行的回调函数。

如果 Promise 成功完成,则调用 onFulfilled() 函数,并将结果作为参数传递给它。如果 Promise 失败,则调用 onRejected() 函数,并将错误作为参数传递给它。

4. Promise 的手写实现

我们可以自己动手实现一个简单的 Promise。它的代码如下:

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

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

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

    this.state = 'fulfilled';
    this.result = result;
    this.onFulfilledCallbacks.forEach(callback => callback(result));
  }

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

    this.state = 'rejected';
    this.result = error;
    this.onRejectedCallbacks.forEach(callback => callback(error));
  }

  then(onFulfilled, onRejected) {
    if (this.state === 'fulfilled') {
      onFulfilled(this.result);
    } else if (this.state === 'rejected') {
      onRejected(this.result);
    } else {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    }

    return this;
  }
}

这个手写的 Promise 与内置的 Promise 具有相同的功能,可以用于处理异步编程。

5. Promise 的应用场景

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

  • AJAX 请求
  • setTimeout() 和 setInterval()
  • 文件读写
  • 网络请求
  • 动画

Promise 可以让异步编程更加简洁高效,避免回调函数的层层嵌套。

总结

Promise 是 JavaScript 中处理异步编程的利器。它可以让我们更加方便地处理异步操作,避免回调地狱问题。在实际开发中,Promise 可以广泛应用于各种场景,例如 AJAX 请求、文件读写、网络请求等。