返回

全景解析 Promise/A+ 规范和测试用例,手把手带你实现原生 Promise

前端

前言

大家好,我是 [你的名字],一名资深 JavaScript 工程师。今天,我将与大家分享我对于 Promise/A+ 规范和测试用例的理解,以及如何手写一个原生 Promise。

Promise 简介

Promise 是一种 JavaScript 对象,用于表示一个异步操作的最终完成或失败及其结果。Promise 提供了一个统一的接口来处理异步操作,使得代码更加清晰和易于管理。

Promise/A+ 规范

为了确保 Promise 的一致性,JavaScript 社区制定了 Promise/A+ 规范。Promise/A+ 规范定义了 Promise 的行为和实现方式,使得不同的 Promise 实现能够相互兼容。

测试用例

为了验证 Promise 的实现是否符合 Promise/A+ 规范,JavaScript 社区制定了一系列测试用例。这些测试用例涵盖了 Promise 的各种常见用法和边界情况。

手写 Promise

下面,我们将一步一步地手写一个原生 Promise。

class Promise {
  constructor(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);
    }
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        try {
          const result = onFulfilled(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      } else if (this.state === 'rejected') {
        try {
          const result = onRejected(this.result);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      } else {
        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);
          }
        });
      }
    });
  }

  catch(onRejected) {
    return this.then(undefined, onRejected);
  }

  finally(onFinally) {
    return this.then(
      (result) => Promise.resolve(onFinally()).then(() => result),
      (error) => Promise.resolve(onFinally()).then(() => { throw error; })
    );
  }

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

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

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

  static all(promises) {
    return new Promise((resolve, reject) => {
      const results = [];
      let pendingCount = promises.length;

      promises.forEach((promise, index) => {
        promise.then(
          (result) => {
            results[index] = result;
            pendingCount--;
            if (pendingCount === 0) resolve(results);
          },
          (error) => {
            reject(error);
          }
        );
      });
    });
  }

  static allSettled(promises) {
    return new Promise((resolve) => {
      const results = [];
      let pendingCount = promises.length;

      promises.forEach((promise, index) => {
        promise
          .then((result) => {
            results[index] = { status: 'fulfilled', value: result };
            pendingCount--;
            if (pendingCount === 0) resolve(results);
          })
          .catch((error) => {
            results[index] = { status: 'rejected', reason: error };
            pendingCount--;
            if (pendingCount === 0) resolve(results);
          });
      });
    });
  }
}

结语

以上就是手写 Promise 的详细过程。希望这篇文章对您有所帮助。如果您有任何问题,欢迎随时提出。