手写Promise思考过程

手写 promise 是前端面试过程中的必考题,今天来温习下手写 promise 过程并写下思考过程,熟悉思路。

基本框架

在 promise 的日常使用中我们经常会看到以下类似代码

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("foo");
  }, 300);
});

myPromise.then(handleFulfilledA, handleRejectedA);

根据以上使用方式我们知道 Promise 是一个构造函数,且有一个函数类型参数 executor,这个函数参数是会立即执行的,且这个函数拥有 resolve 和 reject 这两个函数类型参数。且 Promise 的对象存在一个 then 方法,这个 then 方法里面会有两个参数,一个是成功的回调 onFulfilled,另一个是失败的回调 onRejected,调用 resolve 会执行 onFulfilled,调用 reject 会执行 onRejected。这个方法需要添加在原型上。至此我们可以写出 promise 基本框架

class MyPromise {
  constructor(executor) {
    const resolve = () => {};
    const reject = () => {};
    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {}
}

三种状态

我们知道 promise 中文翻译为承诺,即状态不会轻易改变,其状态只能从 pending 变为 fulfilled 或者从 pending 变为 rejected。resolve 函数执行说明状态变为 fulfilled,reject 函数执行说明状态变为 rejected
故此我们可以完善这三种状态

const STATUS = {
  PENDING: "pending",
  FULFILLED: "fulfilled",
  REJECTED: "rejected",
};

class MyPromise {
  constructor(executor) {
    this.status = STATUS.PENDING; // 初始状态
    this.value = void 0; //  promise成功执行的结果
    this.reason = void 0; // promise被拒绝的原因
    const resolve = (value) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value; // 将结果保存下来方便在onFulfilled回调中使用
      }
    };
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;
      }
    };
    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    if (this.status === STATUS.FULFILLED) {
      // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
      onFulfilled(this.value);
    } else if (this.status === STATUS.REJECTED) {
      // 当状态变为rejected时 执行onRejected回调,且传入相应的值
      onRejected(this.reason);
    }
  }
}

至此一个简易版的 promise 完成了,我们可以来试用下

const p1 = new MyPromise((resolve, reject) => {
  resolve("success");
});
p1.then(
  (res) => {
    console.log("res", res); // res success
  },
  (err) => {
    console.log("err", err);
  }
);

添加异步

上面简易版的 MyPromise 中只能执行同步方法,当其中包含异步调用的时候,then 方法直接跳过了。因为在异步调用中执行 then 方法的时候,状态还未改变仍旧是 pending。等到异步的 Promise 状态发生改变的时候,then 已经执行完了。这里需要改造下 then 方法

const STATUS = {
  PENDING: "pending",
  FULFILLED: "fulfilled",
  REJECTED: "rejected",
};

class MyPromise {
  constructor(executor) {
    this.status = STATUS.PENDING; // 初始状态
    this.value = void 0; //  promise成功执行的结果
    this.reason = void 0; // promise被拒绝的原因
    this.onResolvedCallbacks = []; // 存放所有成功的回调。
    this.onRejectedCallbacks = []; // 存放所有失败的回调。
    const resolve = (value) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value; // 将结果保存下来方便在onFulfilled回调中使用
        this.onResolvedCallbacks.forEach((fn) => fn()); // 将存储的onFulfilled依次执行
      }
    };
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;
        this.onRejectedCallbacks.forEach((fn) => fn()); // 将存储的onRejected依次执行
      }
    };
    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    if (this.status === STATUS.FULFILLED) {
      // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
      onFulfilled(this.value);
    } else if (this.status === STATUS.REJECTED) {
      // 当状态变为rejected时 执行onRejected回调,且传入相应的值
      onRejected(this.reason);
    } else {
      // 状态仍旧是pending
      // 这个时候应该把onFulfilled和onRejected先存起来,当执行了resolve或者reject的时候再执行onFulfilled或onRejected
      this.onResolvedCallbacks.push(() => {
        onFulfilled(this.value);
      });
      this.onRejectedCallbacks.push(() => {
        onRejected(this.reason);
      });
    }
  }
}

添加异步调用试试看结果

const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("success");
  }, 1000);
});
p1.then(
  (res) => {
    console.log("res", res); // res success
  },
  (err) => {
    console.log("err", err);
  }
);

链式调用

我们知道 promise 能够解决回调地狱的根本原因是因为它支持链式调用.
如果一个 then 方法返回普通值,这个值会传递给下一次 then 中,作为成功的结果。
如果返回的是一个 promise,则会把 promise 的执行结果传递下去,并且取决于这个 Promise 的成功或失败。
如果返回的是一个报错就会执行到下一个 then 的失败的函数中。

Promise 的 then 方法返回的是一个全新的 Promise,而不是当前的 Promise。因为 Promise 的状态只能改变一次,如果使用同一个 Promise 的话后面的 then 执行时状态就不能变了。

这里我们来修改下 then 方法

class MyPromise {
  constructor(executor) {
    this.status = STATUS.PENDING; // 初始状态
    this.value = void 0; //  promise成功执行的结果
    this.reason = void 0; // promise被拒绝的原因
    this.onResolvedCallbacks = []; // 存放所有成功的回调。
    this.onRejectedCallbacks = []; // 存放所有失败的回调。
    const resolve = (value) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value; // 将结果保存下来方便在onFulfilled回调中使用
        this.onResolvedCallbacks.forEach((fn) => fn()); // 将存储的onFulfilled依次执行
      }
    };
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;
        this.onRejectedCallbacks.forEach((fn) => fn()); // 将存储的onRejected依次执行
      }
    };
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
  then(onFulfilled, onRejected) {
    //解决 onFulfilled,onRejected 没有传值的问题
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
    //因为错误的值要让后面访问到,所以这里也要抛出个错误,不然会在之后 then 的 resolve 中捕获
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : function (err) {
            throw err;
          };
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.status === STATUS.FULFILLED) {
        // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
        //前一个then方法的返回值会传递给下一个then
        try {
          const x = onFulfilled(this.value); // 这里可能返回promise
          resolve(x);
        } catch (e) {
          // 执行失败需要reject抛出错误
          reject(e);
        }
      } else if (this.status === STATUS.REJECTED) {
        // 当状态变为rejected时 执行onRejected回调,且传入相应的值
        try {
          const x = onRejected(this.reason);
          resolve(x);
        } catch (e) {
          reject(e);
        }
      } else {
        // 状态仍旧是pending
        // 这个时候应该把onFulfilled和onRejected先存起来,当执行了resolve或者reject的时候再执行onFulfilled或onRejected
        this.onResolvedCallbacks.push(() => {
          try {
            const x = onFulfilled(this.value);
            resolve(x);
          } catch (e) {
            reject(e);
          }
        });
        this.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(this.reason);
            resolve(x);
          } catch (e) {
            reject(e);
          }
        });
      }
    });
    return promise2;
  }
}

可以尝试下链式调用

const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("success");
  }, 1000);
});
p1.then().then((res) => {
  console.log("res", res); //res success
});

通过Promise A+ 规范 了解到这里 then 方法中 onFulfilled(this.value)可能返回 promise,这时候需要写一个方法来判断,如果返回值是 promise 就调用 promise,否则才继续向 resolve 传递。
这里定义一个 resolvePromise 方法,在函数中判断返回值 x 和 promise2 的关系以及后续的处理,所以需要传递 promise2 参数,x 参数,resolve 参数和 reject 参数。

function resolvePromise(promise2, x, resolve, reject) {
  //首先判断promise2和x引用了同一个promise对象
  if (promise2 === x) {
    // 防止自己等待自己
    return reject(new TypeError("循环引用了"));
  }
  let called; //表示Promise有没有被调用过 确保只调用一次
  // x是object或者是个function
  if ((x !== null && typeof x === "object") || typeof x === "function") {
    try {
      let then = x.then;
      //如果then是个函数,就认为他是Promise, 需要通过call执行then方法,改变this的指向为x,then中传入成功和失败的函数,官方文档中指明成功函数的参数叫y,失败的参数为r
      if (typeof then === "function") {
        then.call(
          x,
          function (y) {
            if (called) {
              // 是否调用过
              return;
            }
            called = true;
            // y有可能也是一个Promise,所以不能直接写resolve(y),应该递归判断y和promise2的关系。需要调用resolvePromise
            resolvePromise(promise2, y, resolve, reject);
          },
          function (r) {
            if (called) {
              return;
            }
            called = true;
            reject(r);
          }
        );
      }
    } catch (e) {
      if (called) {
        return;
      }
      called = true;
      reject(e);
    }
  } else {
    if (called) {
      return;
    }
    called = true;
    resolve(x);
  }
}

class MyPromise {
  // ...
  then(onFulfilled, onRejected) {
    //解决 onFulfilled,onRejected 没有传值的问题
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
    //因为错误的值要让后面访问到,所以这里也要抛出个错误,不然会在之后 then 的 resolve 中捕获
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : function (err) {
            throw err;
          };
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.status === STATUS.FULFILLED) {
        // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
        //前一个then方法的返回值会传递给下一个then
        try {
          const x = onFulfilled(this.value); // 这里可能返回promise
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          // 执行失败需要reject抛出错误
          reject(e);
        }
      } else if (this.status === STATUS.REJECTED) {
        // 当状态变为rejected时 执行onRejected回调,且传入相应的值
        try {
          const x = onRejected(this.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      } else {
        // 状态仍旧是pending
        // 这个时候应该把onFulfilled和onRejected先存起来,当执行了resolve或者reject的时候再执行onFulfilled或onRejected
        this.onResolvedCallbacks.push(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
        this.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }
    });
    return promise2;
  }
}

promise.then 异步

我们知道 promise.then 会创建一个异步的微任务,这里我们用 queueMicrotask()来创建,改造下 then 方法

class MyPromise {
  // ...
  then(onFulfilled, onRejected) {
    //解决 onFulfilled,onRejected 没有传值的问题
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
    //因为错误的值要让后面访问到,所以这里也要抛出个错误,不然会在之后 then 的 resolve 中捕获
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : function (err) {
            throw err;
          };
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.status === STATUS.FULFILLED) {
        queueMicrotask(() => {
          // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
          //前一个then方法的返回值会传递给下一个then
          try {
            const x = onFulfilled(this.value); // 这里可能返回promise
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            // 执行失败需要reject抛出错误
            reject(e);
          }
        });
      } else if (this.status === STATUS.REJECTED) {
        queueMicrotask(() => {
          // 当状态变为rejected时 执行onRejected回调,且传入相应的值
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      } else {
        // 状态仍旧是pending
        // 这个时候应该把onFulfilled和onRejected先存起来,当执行了resolve或者reject的时候再执行onFulfilled或onRejected
        this.onResolvedCallbacks.push(() => {
          queueMicrotask(() => {
            try {
              const x = onFulfilled(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          });
        });
        this.onRejectedCallbacks.push(() => {
          queueMicrotask(() => {
            try {
              const x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          });
        });
      }
    });
    return promise2;
  }
}

补充 catch 和 finally

catch 其实就是 then 方法失败回调
finally:finally 表示不是最终的意思,而是无论如何都会执行的意思。
如果返回一个 promise 会等待这个 promise 也执行完毕。如果返回的是成功的 promise,会采用上一次的结果;如果返回的是失败的 promise,会用这个失败的结果,传到 catch 中。

class MyPromise {
  //...
  catch(onRejected) {
    return this.then(null, onRejected);
  },
  finally(callback) {
    return this.then(
      (value) => {
        return MyPromise.resolve(callback()).then(() => value);
      },
      (reason) => {
        return MyPromise.resolve(callback()).then(() => {
          throw reason;
        });
      }
    );
  }
}

添加静态方法 resolve reject all race allSettled

class MyPromise {
  constructor(executor) {
    this.status = STATUS.PENDING; // 初始状态
    this.value = void 0; //  promise成功执行的结果
    this.reason = void 0; // promise被拒绝的原因
    this.onResolvedCallbacks = []; // 存放所有成功的回调。
    this.onRejectedCallbacks = []; // 存放所有失败的回调。
    const resolve = (value) => {
      // 如果 value 是一个promise,那也要实现一个递归解析
      if (value instanceof Promise) {
        // 递归解析
        return value.then(resolve, reject);
      }

      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value; // 将结果保存下来方便在onFulfilled回调中使用
        this.onResolvedCallbacks.forEach((fn) => fn()); // 将存储的onFulfilled依次执行
      }
    };
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;
        this.onRejectedCallbacks.forEach((fn) => fn()); // 将存储的onRejected依次执行
      }
    };
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
  // ...
  static resolve(data) {
    return new MyPromise((resolve, reject) => {
      resolve(data); // 产生一个成功的 promise
    });
  }
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
}

promise.all 是解决并发问题的,多个异步并发获取最终的结果(如果有一个失败则失败)。

class MyPromise {
  // ...
  static all(promises) {
    // 判断参数是否可遍历
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise((resolve, reject) => {
      let resultArr = [];
      let orderIndex = 0;
      const processResultByKey = (value, index) => {
        resultArr[index] = value;
        if (++orderIndex === promises.length) {
          resolve(resultArr);
        }
      };
      for (let i = 0; i < promises.length; i++) {
        let value = promises[i];
        if (value && typeof value.then === "function") {
          // value是promise
          value.then((value) => {
            processResultByKey(value, i);
          }, reject);
        } else {
          processResultByKey(value, i);
        }
      }
    });
  }
}

Promise.race 用来处理多个请求,采用最快的(谁先完成用谁的)。

class MyPromise {
  // ...
  static race(promises) {
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        let value = promises[i];
        if (value && typeof value.then === "function") {
          value.then(resolve, reject);
        } else {
          resolve(value);
        }
      }
    });
  }
}

Promise.allSettled()方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。

class MyPromise {
  // ...
  allSettled(promises) {
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise(function (resolve) {
      const len = promises.length;
      const results = [];
      let count = 0;
      promises.forEach((s, index) => {
        MyPromise.resolve(s)
          .then((res) => {
            results[index] = {
              status: "fulfilled",
              value: s,
            };
            if (++count === len) {
              resolve(results);
            }
          })
          .catch((val) => {
            results[index] = {
              status: "reject",
              value: s,
            };
            count++;
            if (count === len) {
              resolve(results);
            }
          });
      });
    });
  }
}

最终完整 MyPromise

const STATUS = {
  PENDING: "pending",
  FULFILLED: "fulfilled",
  REJECTED: "rejected",
};

/**
 * 判断x是否是promise2,如果是promise2就执行并且将执行结果添加到resolve方法中,如果是常量则直接添加到resolve方法中
 * @param {*} promise2
 * @param {*} x
 * @param {*} resolve
 * @param {*} reject
 */
function resolvePromise(promise2, x, resolve, reject) {
  //首先判断promise2和x引用了同一个promise对象
  if (promise2 === x) {
    // 防止自己等待自己
    return reject(new TypeError("循环引用了"));
  }
  let called; //表示Promise有没有被调用过 确保只调用一次
  // x是object或者是个function
  if ((x !== null && typeof x === "object") || typeof x === "function") {
    try {
      let then = x.then;
      //如果then是个函数,就认为他是Promise, 需要通过call执行then方法,改变this的指向为x,then中传入成功和失败的函数,官方文档中指明成功函数的参数叫y,失败的参数为r
      if (typeof then === "function") {
        then.call(
          x,
          function (y) {
            if (called) {
              // 是否调用过
              return;
            }
            called = true;
            // y有可能也是一个Promise,所以不能直接写resolve(y),应该递归判断y和promise2的关系。需要调用resolvePromise
            resolvePromise(promise2, y, resolve, reject);
          },
          function (r) {
            if (called) {
              return;
            }
            called = true;
            reject(r);
          }
        );
      }
    } catch (e) {
      if (called) {
        return;
      }
      called = true;
      reject(e);
    }
  } else {
    if (called) {
      return;
    }
    called = true;
    resolve(x);
  }
}
class MyPromise {
  constructor(executor) {
    this.status = STATUS.PENDING;
    this.value = void 0;
    this.reason = void 0;
    this.onResolvedCallbacks = [];
    this.onRejectedCallbacks = [];
    const resolve = (value) => {
      // promise.resolve 是具备等待功能的。
      // 如果参数是 promise 会等待这个 promise 解析完毕,在向下执行
      if (value instanceof MyPromise) {
        // 递归解析
        return value.then(resolve, reject);
      }
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value;

        this.onResolvedCallbacks.forEach((fn) => fn());
      }
    };
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;

        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    };

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

  then(onFulfilled, onRejected) {
    //解决 onFulfilled,onRejected 没有传值的问题
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
    //因为错误的值要让后面访问到,所以这里也要抛出个错误,不然会在之后 then 的 resolve 中捕获
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : function (err) {
            throw err;
          };
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.status === STATUS.FULFILLED) {
        // 当状态变为fulfilled时 执行onFulfilled回调,且传入相应的值
        //前一个then方法的返回值会传递给下一个then
        try {
          const x = onFulfilled(this.value); // 这里可能返回promise
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          // 执行失败需要reject抛出错误
          reject(e);
        }
      } else if (this.status === STATUS.REJECTED) {
        // 当状态变为rejected时 执行onRejected回调,且传入相应的值
        try {
          const x = onRejected(this.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      } else {
        // 状态仍旧是pending
        // 这个时候应该把onFulfilled和onRejected先存起来,当执行了resolve或者reject的时候再执行onFulfilled或onRejected
        this.onResolvedCallbacks.push(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
        this.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }
    });
    return promise2;
  }
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  finally(callback) {
    return this.then(
      (value) => {
        return MyPromise.resolve(callback()).then(() => value);
      },
      (reason) => {
        return MyPromise.resolve(callback()).then(() => {
          throw reason;
        });
      }
    );
  }
  static resolve(data) {
    return new MyPromise((resolve, reject) => {
      resolve(data);
    });
  }
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
  static all(promises) {
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise((resolve, reject) => {
      let resultArr = [];
      let orderIndex = 0;
      const processResultByKey = (value, index) => {
        resultArr[index] = value;
        if (++orderIndex === promises.length) {
          resolve(resultArr);
        }
      };
      for (let i = 0; i < promises.length; i++) {
        let value = promises[i];
        if (value && typeof value.then === "function") {
          value.then((value) => {
            processResultByKey(value, i);
          }, reject);
        } else {
          processResultByKey(value, i);
        }
      }
    });
  }
  static race(promises) {
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        let value = promises[i];
        if (value && typeof value.then === "function") {
          value.then(resolve, reject);
        } else {
          resolve(value);
        }
      }
    });
  }

  static allSettled(promises) {
    if (!Array.isArray(promises)) {
      const type = typeof promises;
      return new TypeError(`TypeError: ${type} ${promises} is not iterable`);
    }
    return new MyPromise(function (resolve) {
      const len = promises.length;
      const results = [];
      let count = 0;
      promises.forEach((s, index) => {
        MyPromise.resolve(s)
          .then((res) => {
            results[index] = {
              status: "fulfilled",
              value: s,
            };
            if (++count === len) {
              resolve(results);
            }
          })
          .catch((val) => {
            results[index] = {
              status: "reject",
              value: s,
            };
            count++;
            if (count === len) {
              resolve(results);
            }
          });
      });
    });
  }
}

参考文章:
手写 Promise 源码,再深入理解 Promise 机制