返回

初心如磐,以JavaScriptPromise揭开Promise A+的神秘面纱

前端

初识Promise

在JavaScript的世界里,异步编程是一个不可回避的话题。从简单的计时器到复杂的HTTP请求,我们都需要处理各种各样的异步操作。在没有Promise之前,回调函数是处理异步操作的常见方式。然而,随着异步操作的增多,回调函数的嵌套层级也越来越深,导致代码变得难以理解和维护,这就是臭名昭著的“回调地狱”。

Promise应运而生,它是一种用于处理异步操作的解决方案。它提供了一种更简洁、更可读的方式来组织和控制异步操作。与回调函数不同,Promise允许我们以同步的方式编写异步代码,从而使代码更加易于理解和维护。

Promise A+规范

为了确保Promise的实现具有可预测性和一致性,ECMAScript技术委员会制定了Promise A+规范。该规范定义了Promise的基本行为和接口,包括Promise的状态、链式调用、静态方法和错误处理等。

Promise的状态

Promise有三种状态:pending(等待)、fulfilled(已完成)和rejected(已拒绝)。

  • pending:这是Promise的初始状态,表示异步操作尚未完成。
  • fulfilled:当异步操作成功完成时,Promise进入fulfilled状态。
  • rejected:当异步操作失败时,Promise进入rejected状态。

链式调用

Promise的链式调用是指将多个Promise连接起来,以便当一个Promise完成时,自动触发下一个Promise的执行。链式调用的语法如下:

promise1.then(function(result) {
  // 处理promise1成功完成后的结果
  return promise2;
}).then(function(result) {
  // 处理promise2成功完成后的结果
  return promise3;
}).then(function(result) {
  // 处理promise3成功完成后的结果
});

静态方法

Promise还提供了一些静态方法,用于创建和处理Promise。这些方法包括:

  • Promise.all:用于等待多个Promise同时完成,并返回一个包含所有Promise结果的数组。
  • Promise.race:用于等待第一个完成的Promise,并返回其结果。
  • Promise.reject:用于创建一个rejected状态的Promise。
  • Promise.resolve:用于创建一个fulfilled状态的Promise。

错误处理

当Promise进入rejected状态时,可以捕获错误并进行处理。错误处理的语法如下:

promise.catch(function(error) {
  // 处理promise执行过程中发生的错误
});

实现自己的Promise

现在,让我们开始实现自己的Promise。我们将按照Promise A+规范的要求,一步一步地完成这个任务。

1. 定义Promise的构造函数

首先,我们需要定义Promise的构造函数。该构造函数接受一个参数,即执行器(executor)。执行器是一个函数,它接收两个参数:resolve和reject。这两个参数用于将Promise的状态从pending改变为fulfilled或rejected。

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

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

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

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

2. 实现then方法

then方法是Promise最重要的一个方法。它允许我们对Promise的状态进行监听,并在Promise完成时执行相应的回调函数。then方法的语法如下:

then(onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    if (this.state === 'pending') {
      this.onFulfilledCallbacks.push(() => {
        try {
          const result = onFulfilled(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });

      this.onRejectedCallbacks.push(() => {
        try {
          const result = onRejected(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
    } else if (this.state === 'fulfilled') {
      setTimeout(() => {
        try {
          const result = onFulfilled(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      }, 0);
    } else if (this.state === 'rejected') {
      setTimeout(() => {
        try {
          const result = onRejected(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      }, 0);
    }
  });
}

3. 实现静态方法

Promise的静态方法包括Promise.all、Promise.race、Promise.reject和Promise.resolve。

static all(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let count = 0;
    promises.forEach((promise, index) => {
      promise.then((result) => {
        results[index] = result;
        count++;
        if (count === promises.length) {
          resolve(results);
        }
      }, reject);
    });
  });
}

static race(promises) {
  return new Promise((resolve, reject) => {
    promises.forEach((promise) => {
      promise.then(resolve, reject);
    });
  });
}

static reject(error) {
  return new Promise((resolve, reject) => {
    reject(error);
  });
}

static resolve(value) {
  return new Promise((resolve, reject) => {
    resolve(value);