返回

解剖Promise:揭开异步编程的奥秘

前端

Promise,异步编程的救星

在JavaScript中,异步编程是家常便饭。当我们需要处理耗时操作,比如网络请求、文件读写、定时器等,就需要用到异步编程。而Promise,就是专门为异步编程而生的利器。它让我们可以更优雅地处理异步操作,避免传统的回调地狱。

Promise/A+规范,统一的标准

为了让Promise在不同环境下都能发挥作用,诞生了Promise/A+规范。该规范定义了Promise必须遵守的规则,确保其行为一致。有了这个规范,我们就可以放心地在不同的环境中使用Promise,而不用担心兼容性问题。

Promise的原理,从内而外

Promise的原理其实并不复杂。它就是一个具有三种状态的对象:pending(等待)、fulfilled(成功)和rejected(失败)。当我们创建一个Promise时,它会立即执行executor函数。executor函数接受两个参数,分别是resolve和reject。当异步操作成功时,我们调用resolve来将Promise的状态由pending变为fulfilled;当异步操作失败时,我们调用reject来将Promise的状态由pending变为rejected。

Promise的then方法,then与then之间的故事

then方法是Promise最重要的API之一。它允许我们在Promise成功或失败时执行相应的操作。then方法接受两个参数,分别是onFulfilled和onRejected。onFulfilled是当Promise成功时执行的函数,onRejected是当Promise失败时执行的函数。

源码实现,从零构建Promise

为了加深对Promise的理解,我们从零构建一个符合Promise/A+规范的Promise实现。

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

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

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

    executor(resolve, reject);
  }

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

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

这个Promise实现遵循了Promise/A+规范,并且可以满足我们日常异步编程的需求。

结语

Promise是JavaScript异步编程的重要工具,它让我们可以更优雅地处理异步操作,避免传统的回调地狱。通过深入分析Promise的原理,以及从零构建Promise的实现,我们对Promise有了更深入的理解。希望这些知识能够帮助你更好地掌握Promise,并将其应用到你的项目中。