前置知识

Promise 有三个状态:pending (等待)fulfilled (成功)rejected (失败),状态一旦改变就不可逆;

  1. 状态只能从 pending -> fulfilledpending -> rejected
  2. 每个 Promise 实例都有 then 方法,用于注册成功 / 失败的回调;
  3. 回调函数会异步执行;

手写 Promise/A+

第一步:实现基础的 Promise 结构(状态 + 结果)

  1. 实现思路:

    1. 定义 Promise 类,初始化状态为 pending
    2. 构造函数接收一个执行器函数 executor,该函数立即执行;
    3. 实现 resolvereject 方法,用于改变状态和保存结果;
    4. 状态一旦改变,不能再修改;
  2. 代码实现:

    // 第一步:基础结构
    class MyPromise {
      // 定义三个静态状态常量
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        // 初始化状态
        this.status = MyPromise.PENDING;
        // 成功结果
        this.value = undefined;
        // 失败原因
        this.reason = undefined;
    
        // 成功回调:改变状态 + 保存结果
        const resolve = (value) => {
          // 状态不可逆:只有pending状态才能修改
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
          }
        };
    
        // 失败回调:改变状态 + 保存原因
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
          }
        };
    
        // 执行器函数立即执行,捕获执行过程中的异常
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    }
    
    // 测试1:基础状态和结果
    const p1 = new MyPromise((resolve, reject) => {
      resolve('成功结果');
    });
    console.log('p1状态:', p1.status); // 输出: fulfilled
    console.log('p1结果:', p1.value); // 输出: 成功结果
    
    // 测试2:状态不可逆
    const p2 = new MyPromise((resolve, reject) => {
      resolve('第一次resolve');
      reject('reject不会生效'); // 状态已改为fulfilled,reject无效
    });
    console.log('p2状态:', p2.status); // 输出: fulfilled
    console.log('p2结果:', p2.value); // 输出: 第一次resolve
    
    // 测试3:捕获执行器异常
    const p3 = new MyPromise((resolve, reject) => {
      throw new Error('执行器出错了');
    });
    console.log('p3状态:', p3.status); // 输出: rejected
    console.log('p3原因:', p3.reason); // 输出: Error: 执行器出错了
    
  3. 解析:

    1. 状态常量:用静态常量定义三个状态,避免魔法字符串,提高代码可读性;
    2. 构造函数:接收执行器函数 executor,并立即执行;
    3. resolve/reject:核心逻辑是状态校验,只有 pending 状态才能修改状态,保证状态不可逆;
    4. 异常捕获:用 try/catch 包裹执行器执行逻辑,执行器内部抛出的异常会直接调用 reject

第二步:实现 then 方法(基础版)

  1. 实现思路:

    1. then 方法接收两个参数:onFulfilled (成功回调)onRejected (失败回调)
    2. 根据当前 Promise 状态,执行对应的回调函数;
    3. 回调函数的参数是 Promisevaluereason
  2. 代码实现:

    class MyPromise {
      // 第一步的代码(省略,保持和上面一致)
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
    
        const resolve = (value) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
          }
        };
    
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    
      // 第二步:实现then方法
      then(onFulfilled, onRejected) {
        // 状态为fulfilled,执行成功回调
        if (this.status === MyPromise.FULFILLED) {
          onFulfilled(this.value);
        }
    
        // 状态为rejected,执行失败回调
        if (this.status === MyPromise.REJECTED) {
          onRejected(this.reason);
        }
      }
    }
    
    // 测试1:成功状态的then回调
    const p1 = new MyPromise((resolve) => {
      resolve('成功的值');
    }).then(
      (value) => {
        console.log('成功回调:', value); // 输出: 成功回调: 成功的值
      },
      (reason) => {
        console.log('失败回调:', reason); // 不会执行
      }
    );
    
    // 测试2:失败状态的then回调
    const p2 = new MyPromise((resolve, reject) => {
      reject('失败的原因');
    }).then(
      (value) => {
        console.log('成功回调:', value); // 不会执行
      },
      (reason) => {
        console.log('失败回调:', reason); // 输出: 失败回调: 失败的原因
      }
    );
    
    // 测试3:执行器异常触发失败回调
    const p3 = new MyPromise(() => {
      throw new Error('执行器异常');
    }).then(null, (reason) => {
      console.log('捕获异常:', reason.message); // 输出: 捕获异常: 执行器异常
    });
    
  3. 解析:

    1. then 方法参数:onFulfilled 是成功时的回调,onRejected 是失败时的回调,参数可选 (这里先不处理不传的情况)
    2. 状态判断:根据当前 Promise 的状态,执行对应的回调函数,并把 value/reason 作为参数传入;
    3. 局限性:这个版本的 then 只能处理同步执行器,如果执行器里是异步操作 (比如 setTimeout)then 执行时状态还是 pending,回调不会执行 (第三步解决这个问题)

第三步:支持异步执行器(保存回调队列)

  1. 实现思路:

    1. then 执行时状态还是 pending,说明是异步操作,需要把回调函数保存到队列中;
    2. resolve/reject 执行时,遍历回调队列,执行对应的回调;
    3. 保证异步操作完成后,回调能被执行;
  2. 代码实现:

    class MyPromise {
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
    
        // 新增:保存成功/失败的回调队列(处理异步)
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];
    
        const resolve = (value) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
    
            // 新增:状态改变后,执行所有保存的成功回调
            this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
          }
        };
    
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
    
            // 新增:状态改变后,执行所有保存的失败回调
            this.onRejectedCallbacks.forEach((callback) => callback(this.reason));
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    
      then(onFulfilled, onRejected) {
        if (this.status === MyPromise.FULFILLED) {
          onFulfilled(this.value);
        }
    
        if (this.status === MyPromise.REJECTED) {
          onRejected(this.reason);
        }
    
        // 新增:pending状态时,保存回调到队列
        if (this.status === MyPromise.PENDING) {
          this.onFulfilledCallbacks.push(onFulfilled);
          this.onRejectedCallbacks.push(onRejected);
        }
      }
    }
    
    // 测试1:异步resolve
    const p1 = new MyPromise((resolve) => {
      setTimeout(() => {
        resolve('异步成功的值');
      }, 1000);
    }).then((value) => {
      console.log('异步成功回调:', value); // 1秒后输出: 异步成功回调: 异步成功的值
    });
    
    // 测试2:异步reject
    const p2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        reject('异步失败的原因');
      }, 1000);
    }).then(null, (reason) => {
      console.log('异步失败回调:', reason); // 1秒后输出: 异步失败回调: 异步失败的原因
    });
    
    // 测试3:多个then回调(都能执行)
    const p3 = new MyPromise((resolve) => {
      setTimeout(() => {
        resolve('多个回调共享结果');
      }, 1000);
    });
    // 第一个then
    p3.then((value) => {
      console.log('第一个回调:', value); // 1秒后输出: 第一个回调: 多个回调共享结果
    });
    // 第二个then
    p3.then((value) => {
      console.log('第二个回调:', value); // 1秒后输出: 第二个回调: 多个回调共享结果
    });
    
  3. 解析:

    1. 回调队列:新增 onFulfilledCallbacksonRejectedCallbacks 数组,用于保存异步场景下的回调函数;
    2. pending 处理:当 then 执行时状态还是 pending,说明执行器里是异步操作,把回调函数 push 到对应的队列中;
    3. 回调执行:当 resolve/reject 被调用时,状态改变,同时遍历回调队列,执行所有保存的回调函数;
    4. then 支持:一个 Promise 可以调用多次 then,所有回调都会被保存到队列,最终都会执行;

第四步:实现 then 方法的链式调用

  1. 实现思路:

    1. then 方法必须返回一个新的 Promise 实例 (核心:链式调用的基础)
    2. 回调函数的返回值会作为新 Promiseresolve 参数;
    3. 如果回调函数抛出异常,新 Promisereject 这个异常;
    4. 如果回调返回的是一个 Promise,新 Promise 会等待这个 Promise 完成;
  2. 代码实现:

    class MyPromise {
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];
    
        const resolve = (value) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
            this.onFulfilledCallbacks.forEach((callback) => callback());
          }
        };
    
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
            this.onRejectedCallbacks.forEach((callback) => callback());
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    
      then(onFulfilled, onRejected) {
        // 处理回调不传的情况(兼容规范)
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason };
    
        // 核心:返回新的Promise,实现链式调用
        const newPromise = new MyPromise((resolve, reject) => {
          // 成功状态处理
          if (this.status === MyPromise.FULFILLED) {
            // 用setTimeout模拟微任务(符合Promise/A+规范)
            setTimeout(() => {
              try {
                // 执行成功回调,获取返回值
                const result = onFulfilled(this.value);
                // 处理返回值,决定新Promise的状态
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error); // 回调抛出异常,新Promise reject
              }
            }, 0);
          }
    
          // 失败状态处理
          if (this.status === MyPromise.REJECTED) {
            setTimeout(() => {
              try {
                const result = onRejected(this.reason);
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error);
              }
            }, 0);
          }
    
          // pending状态处理(异步)
          if (this.status === MyPromise.PENDING) {
            this.onFulfilledCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onFulfilled(this.value);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
    
            this.onRejectedCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onRejected(this.reason);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
          }
        });
    
        return newPromise;
      }
    
      // 新增:处理then回调的返回值(核心工具函数)
      resolvePromise(newPromise, result, resolve, reject) {
        // 避免循环引用(自己返回自己)
        if (newPromise === result) {
          return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
    
        // 如果返回值是Promise实例
        if (result instanceof MyPromise) {
          result.then(resolve, reject);
        } else {
          // 普通值,直接resolve
          resolve(result);
        }
      }
    }
    
    // 测试1:基础链式调用
    new MyPromise((resolve) => {
      resolve(1);
    })
      .then((value) => {
        console.log('第一步:', value); // 输出: 第一步: 1
        return value + 1; // 返回普通值,作为下一个then的参数
      })
      .then((value) => {
        console.log('第二步:', value); // 输出: 第二步: 2
        return value + 1;
      })
      .then((value) => {
        console.log('第三步:', value); // 输出: 第三步: 3
      });
    
    // 测试2:返回Promise的链式调用
    new MyPromise((resolve) => {
      resolve(1);
    })
      .then((value) => {
        // 返回一个新的Promise
        return new MyPromise((resolve) => {
          setTimeout(() => {
            resolve(value + 10);
          }, 500);
        });
      })
      .then((value) => {
        console.log('异步返回:', value); // 500ms后输出: 异步返回: 11
      });
    
    // 测试3:回调抛出异常
    new MyPromise((resolve) => {
      resolve(1);
    })
      .then((value) => {
        throw new Error('回调出错了');
      })
      .then(
        (value) => {
          console.log('成功回调:', value); // 不会执行
        },
        (reason) => {
          console.log('捕获异常:', reason.message); // 输出: 捕获异常: 回调出错了
        }
      );
    
    // 测试4:不传回调的穿透
    new MyPromise((resolve) => {
      resolve('穿透的值');
    })
      .then() // 不传回调,值会穿透
      .then() // 继续穿透
      .then((value) => {
        console.log('穿透结果:', value); // 输出: 穿透结果: 穿透的值
      });
    
    // 测试5:循环引用(报错)
    const p = new MyPromise((resolve) => {
      resolve();
    });
    const p2 = p.then(() => {
      return p2; // 返回自己,循环引用
    });
    p2.then(null, (reason) => {
      console.log('循环引用错误:', reason.message); // 输出: Chaining cycle detected for promise #<Promise>
    });
    
  3. 解析:

    1. 返回新 Promisethen 方法必须返回新的 Promise 实例,这是链式调用的核心 (每个 then 都是一个新的 Promise)
    2. 微任务模拟:用 setTimeout 模拟 Promise 的微任务执行 (实际 Promise 是微任务,setTimeout 是宏任务,这里简化实现)
    3. 回调默认值:处理 then 不传回调的情况,成功回调默认返回值本身,失败回调默认抛出异常 (实现值穿透)
    4. resolvePromise 工具函数:
      1. 避免循环引用:如果回调返回的 Promise 是当前新创建的 Promise,直接抛出异常;
      2. 处理 Promise 返回值:如果回调返回 Promise,等待这个 Promise 完成,把它的结果传给新 Promiseresolve/reject
      3. 处理普通值:直接 resolve 普通值;
    5. 异常捕获:每个回调执行都用 try/catch 包裹,抛出的异常会让新 Promise 进入 rejected 状态;

第五步:实现 catch 方法(语法糖)

  1. 实现思路:

    1. catch 方法是 then(null, onRejected) 的语法糖;
    2. 直接复用 then 方法的逻辑,简化失败回调的注册;
  2. 代码实现:

    class MyPromise {
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];
    
        const resolve = (value) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
            this.onFulfilledCallbacks.forEach((callback) => callback());
          }
        };
    
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
            this.onRejectedCallbacks.forEach((callback) => callback());
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    
      then(onFulfilled, onRejected) {
        // 处理回调不传的情况(兼容规范)
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason };
    
        // 核心:返回新的Promise,实现链式调用
        const newPromise = new MyPromise((resolve, reject) => {
          // 成功状态处理
          if (this.status === MyPromise.FULFILLED) {
            // 用setTimeout模拟微任务(符合Promise/A+规范)
            setTimeout(() => {
              try {
                // 执行成功回调,获取返回值
                const result = onFulfilled(this.value);
                // 处理返回值,决定新Promise的状态
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error); // 回调抛出异常,新Promise reject
              }
            }, 0);
          }
    
          // 失败状态处理
          if (this.status === MyPromise.REJECTED) {
            setTimeout(() => {
              try {
                const result = onRejected(this.reason);
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error);
              }
            }, 0);
          }
    
          // pending状态处理(异步)
          if (this.status === MyPromise.PENDING) {
            this.onFulfilledCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onFulfilled(this.value);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
    
            this.onRejectedCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onRejected(this.reason);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
          }
        });
    
        return newPromise;
      }
    
      // 新增:处理then回调的返回值(核心工具函数)
      resolvePromise(newPromise, result, resolve, reject) {
        // 避免循环引用(自己返回自己)
        if (newPromise === result) {
          return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
    
        // 如果返回值是Promise实例
        if (result instanceof MyPromise) {
          result.then(resolve, reject);
        } else {
          // 普通值,直接resolve
          resolve(result);
        }
      }
    
      // 新增:catch方法
      catch(onRejected) {
        return this.then(null, onRejected);
      }
    }
    
    // 测试1:基础catch使用
    new MyPromise((resolve, reject) => {
      reject('失败原因');
    })
      .catch((reason) => {
        console.log('catch捕获:', reason); // 输出: catch捕获: 失败原因
      });
    
    // 测试2:链式调用中的catch
    new MyPromise((resolve) => {
      resolve(1);
    })
      .then((value) => {
        throw new Error('链式中的错误');
      })
      .catch((reason) => {
        console.log('链式catch:', reason.message); // 输出: 链式catch: 链式中的错误
      });
    
    // 测试3:catch后继续链式调用
    new MyPromise((resolve, reject) => {
      reject('初始错误');
    })
      .catch((reason) => {
        console.log('处理错误:', reason); // 输出: 处理错误: 初始错误
        return '错误已处理'; // 返回值作为下一个then的参数
      })
      .then((value) => {
        console.log('处理后的结果:', value); // 输出: 处理后的结果: 错误已处理
      });
    
  3. 解析:

    1. 语法糖本质:catch 方法内部直接调用 then(null, onRejected),完全复用 then 方法的逻辑,无需重复编写;
    2. 链式恢复:catch 方法也返回新的 Promise,所以可以继续链式调用 then,实现 “错误处理后继续执行” 的逻辑;

第六步:实现静态方法(resolve/reject/all)

  1. 实现思路:

    1. MyPromise.resolve:快速创建一个已成功的 Promise
    2. MyPromise.reject:快速创建一个已失败的 Promise
    3. MyPromise.all:接收 Promise 数组,全部成功才成功,有一个失败就失败;
  2. 代码实现:

    class MyPromise {
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';
    
      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];
    
        const resolve = (value) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
            this.onFulfilledCallbacks.forEach((callback) => callback());
          }
        };
    
        const reject = (reason) => {
          if (this.status === MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.reason = reason;
            this.onRejectedCallbacks.forEach((callback) => callback());
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (error) {
          reject(error);
        }
      }
    
      then(onFulfilled, onRejected) {
        // 处理回调不传的情况(兼容规范)
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason };
    
        // 核心:返回新的Promise,实现链式调用
        const newPromise = new MyPromise((resolve, reject) => {
          // 成功状态处理
          if (this.status === MyPromise.FULFILLED) {
            // 用setTimeout模拟微任务(符合Promise/A+规范)
            setTimeout(() => {
              try {
                // 执行成功回调,获取返回值
                const result = onFulfilled(this.value);
                // 处理返回值,决定新Promise的状态
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error); // 回调抛出异常,新Promise reject
              }
            }, 0);
          }
    
          // 失败状态处理
          if (this.status === MyPromise.REJECTED) {
            setTimeout(() => {
              try {
                const result = onRejected(this.reason);
                this.resolvePromise(newPromise, result, resolve, reject);
              } catch (error) {
                reject(error);
              }
            }, 0);
          }
    
          // pending状态处理(异步)
          if (this.status === MyPromise.PENDING) {
            this.onFulfilledCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onFulfilled(this.value);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
    
            this.onRejectedCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const result = onRejected(this.reason);
                  this.resolvePromise(newPromise, result, resolve, reject);
                } catch (error) {
                  reject(error);
                }
              }, 0);
            });
          }
        });
    
        return newPromise;
      }
    
      // 新增:处理then回调的返回值(核心工具函数)
      resolvePromise(newPromise, result, resolve, reject) {
        // 避免循环引用(自己返回自己)
        if (newPromise === result) {
          return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
    
        // 如果返回值是Promise实例
        if (result instanceof MyPromise) {
          result.then(resolve, reject);
        } else {
          // 普通值,直接resolve
          resolve(result);
        }
      }
    
      catch(onRejected) {
        return this.then(null, onRejected);
      }
    
      // 新增:静态resolve方法
      static resolve(value) {
        // 如果value是Promise实例,直接返回
        if (value instanceof MyPromise) {
          return value;
        }
        // 否则创建一个已resolve的Promise
        return new MyPromise((resolve) => {
          resolve(value);
        });
      }
    
      // 新增:静态reject方法
      static reject(reason) {
        return new MyPromise((resolve, reject) => {
          reject(reason);
        });
      }
    
      // 新增:静态all方法
      static all(promises) {
        return new MyPromise((resolve, reject) => {
          // 校验参数是数组
          if (!Array.isArray(promises)) {
            return reject(new TypeError('The argument must be an array'));
          }
    
          const results = []; // 保存所有成功结果
          let completedCount = 0; // 已完成的Promise数量
    
          // 空数组直接resolve
          if (promises.length === 0) {
            return resolve(results);
          }
    
          // 遍历处理每个Promise
          promises.forEach((promise, index) => {
            // 用resolve包装,确保处理的是Promise(兼容普通值)
            MyPromise.resolve(promise).then(
              (value) => {
                completedCount++;
                results[index] = value; // 按原数组顺序保存结果
    
                // 所有Promise都完成,resolve结果数组
                if (completedCount === promises.length) {
                  resolve(results);
                }
              },
              (reason) => {
                // 有一个失败,直接reject
                reject(reason);
              }
            );
          });
        });
      }
    }
    
    // 测试1:MyPromise.resolve
    MyPromise.resolve(100).then((value) => {
      console.log('resolve静态方法:', value); // 输出: resolve静态方法: 100
    });
    // 传入Promise实例
    const p = new MyPromise((resolve) => resolve(200));
    MyPromise.resolve(p).then((value) => {
      console.log('resolve传入Promise:', value); // 输出: resolve传入Promise: 200
    });
    
    // 测试2:MyPromise.reject
    MyPromise.reject('静态reject').catch((reason) => {
      console.log('reject静态方法:', reason); // 输出: reject静态方法: 静态reject
    });
    
    // 测试3:MyPromise.all 全部成功
    const p1 = MyPromise.resolve(1);
    const p2 = new MyPromise((resolve) => setTimeout(() => resolve(2), 500));
    const p3 = 3; // 普通值
    MyPromise.all([p1, p2, p3]).then((values) => {
      console.log('all全部成功:', values); // 500ms后输出: [1, 2, 3]
    });
    
    // 测试4:MyPromise.all 有失败
    const p4 = MyPromise.resolve(1);
    const p5 = MyPromise.reject('失败了');
    MyPromise.all([p4, p5]).catch((reason) => {
      console.log('all有失败:', reason); // 输出: all有失败: 失败了
    });
    
  3. 解析:

    1. static resolve
      1. 如果参数是 Promise 实例,直接返回 (避免重复包装)
      2. 如果是普通值,创建一个新的 Promiseresolve 这个值;
    2. static reject:直接创建一个新的 Promisereject 传入的原因;
    3. static all
      1. 校验参数类型:必须是数组,否则抛出异常;
      2. 结果顺序:按原数组顺序保存结果 (即使某个 Promise 异步完成)
      3. 失败快速返回:只要有一个 Promise 失败,立即 reject 这个原因;
      4. 兼容普通值:用 MyPromise.resolve 包装每个元素,确保能处理普通值;

总结

  1. 一步步实现了一个核心功能完整的 Promise,核心关键点回顾:

    1. 状态管理:Promisepending/fulfilled/rejected 三个状态,状态一旦改变不可逆,这是 Promise 的核心特性;
    2. then 方法:
      1. 支持同步 / 异步执行器 (通过回调队列实现)
      2. 返回新的 Promise 实现链式调用,回调返回值会作为新 Promise 的结果;
      3. resolvePromise 处理回调返回的 Promise,实现嵌套 Promise 的扁平化;
    3. 核心扩展:
      1. catchthen(null, onRejected) 的语法糖,简化错误处理;
      2. 静态方法 (resolve/reject/all) 是常用的语法糖,提升开发效率;
      3. 所有异步回调都通过异步执行 (模拟微任务),符合 Promise/A+ 规范;
  2. 这个实现覆盖了 Promise 的核心功能,虽然和浏览器原生 Promise (如微任务、更多静态方法) 还有差距,但足以理解 Promise 的核心原理;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 前置知识
  2. 2. 手写 Promise/A+
    1. 2.1. 第一步:实现基础的 Promise 结构(状态 + 结果)
    2. 2.2. 第二步:实现 then 方法(基础版)
    3. 2.3. 第三步:支持异步执行器(保存回调队列)
    4. 2.4. 第四步:实现 then 方法的链式调用
    5. 2.5. 第五步:实现 catch 方法(语法糖)
    6. 2.6. 第六步:实现静态方法(resolve/reject/all)
  3. 3. 总结