Skip to content

手写Promise

Posted on:2024年1月27日 at 18:37

手写Promise

构造函数

then

catch

Promise.resolve()

Promise.reject()

Promise.reject = function (err) {
  return new Promise((resolve, reject) => {
    reject(err);
  });
};

Promise.all()

Promise.all() 返回一个合成的 Promise 实例。只有当每个包含的 Promise 实例都解决(fulfilled)后才解决(fulfilled),如果有一个包含的 Promise 实例拒绝(rejected)了,则合成的 Promise 也会拒绝(rejected)。

Promise.all = function (promiseList) {
  let count = 0;
  let result = [];
  const length = promiseList.length;
  return new Promise((resolve, reject) => {
    promiseList.forEach(
      (p, index) => {
        p.then(res => {
          result[index] = res;
          count++;
          if (count === length) {
            resolve(result);
          }
        });
      },
      err => {
        reject(err);
      }
    );
  });
};

Promise.race()

Promise.race() 返回一个合成的 Promise 实例。其会返回这一组中最先解决(fulfilled)或拒绝(rejected)的 Promise 实例的返回值。

Promise.race = function (promiseList) {
  return new Promise((resolve, reject) => {
    promiseList.forEach(promise => {
      promise.then(
        res => {
          resolve(res);
        },
        err => {
          reject(err);
        }
      );
    });
  });
};

Promise.any()

Promise.any() 相当于 Promise.all() 的反向操作,同样返回一个合成的 Promise 实例。只要其中包含的任何一个 Promise 实例解决(fulfilled)了,合成的 Promise 就解决(fulfilled)。

只有当每个包含的 Promise 都拒绝(rejected)了,合成的 Promise 才拒绝(rejected)。

Promise.any = function (promiseList) {
  let count = 0;
  const res = [];
  const length = promiseList.length;
  return new Promise((resolve, reject) => {
    promiseList.forEach((promise, index) => {
      promise.then(
        res => {
          resolve(res);
        },
        err => {
          count++;
          res[index] = err;
          if (count === length) {
            reject(err);
          }
        }
      );
    });
  });
};

Promise.allSettled()

Promise.allSettled() 返回一个合成的 Promise 实例。等到所有包含的每个 Promise 实例都返回结果落定时,不管是解决(fulfilled)还是拒绝(rejected),合成的 Promise 才会结束。一旦结束,状态总是 fulfilled。

其返回的是一个对象数组,每个对象表示对应的 Promise 结果。

对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。

Promise.allSettled = function (promiseList) {
  const result = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promiseList.forEach((promise, index) => {
      promise.then(
        val => {
          result[index] = {
            status: "fulfilled",
            value: val,
          };
          count++;
          if (count === promiseList.length) {
            resolve(result);
          }
        },
        err => {
          result[index] = {
            status: "rejected",
            reason: err,
          };
          count++;
          if (count === promiseList.length) {
            resolve(result);
          }
        }
      );
    });
  });
};

应用场景

PromisePool

async function promisePool(functions, n) {
  const resolved = [];
  const queue = new Set();
  for (const task of functions) {
    const x = task().then(res => {
      resolved.push(res);
      queue.delete(x);
    });
    queue.add(x);
    if (queue.size >= n) await Promise.race(queue);
  }
  await Promise.allSettled(queue);
  return resolved;
}