Skip to content

Promise 系列

先来个小工具 wait

动机好像是很多语言里都有一个类似的 sleep 函数专门用来阻塞线程?

js
// MDN中的wait函数,意思是专门搞一个用于等待的promise,妙啊
const wait = (time) => new Promise((resolve) => setTimeout(resolve, time));

// sleep函数,setTimeout实现
const sleep = (fun, time) => {
  setTimeout(fun(), time);
};
sleep(fun, 2000);

// sleep函数promise实现
const sleep2 = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time);
  });
sleep2(2000).then(fn);

// sleep函数async实现
async function sleep3(time) {
  await sleep2(time);
  fun();
}
sleep3(2000);

经久不衰的 promise.all

从 MDN 文档看,promise.all 接收一个可迭代的容器(可以当作是数组),返回一个新的 promise 实例 数组中每个 promise 实例都 resolve 才 resolve,有一个 reject 就全部 reject

js
Promise.Myall = function (promiseArr) {
  let resultArr = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promiseArr.forEach((item, index) => {
      // 统一resolve一下保证全是promise
      Promise.resolve(item).then((res) => {
        resultArr[index] = res;
        count++;
        // 全部resolve就整体resolve
        if (count === promiseArr.length) {
          resolve(resultArr);
        }
      });
    });
  });
};

promise.race

输入输出是类似的 逻辑上 race 中只要有任意 promise 实例 settle,就返回最快 settle 的

js
Promise.Myrace = function (promiseArr) {
  return new Promise((resolve, reject) => {
    promiseArr.forEach((item) => {
      // 有任意promise项resolve或者reject都直接返回
      Promise.resolve(item).then(resolve).catch(reject);
    });
  });
};

promise.any

和 any 是一对,只要有一个 promise resolve 就整体 resolve,且返回最快 resolve 的,全部 reject 才 reject

js
Promise.Myany = function (promiseArr) {
  let Arr = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promiseArr.forEach((item, index) => {
      Promise.resolve(item).then(resolve, (err) => {
        // 这里reject结果需要具体一点标明状态
        Arr[index] = { status: "rejected", val: err };
        count++;
        if (count === promiseArr.length) {
          reject(new Error("all promise rejected"));
        }
      });
    });
  });
};

promise.allSettled 我全都要

这个逻辑就是等所有 promise 都 settle 了再全部返回结果

js
Promise.MyallSettled = function (promiseArr) {
  let resultArr = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promiseArr.forEach((item, index) => {
      Promise.resolve(item)
        .then((resolve) => {
          // 最大的区别就是都要具体写状态
          resultArr[index] = { status: "fulfilled", val: resolve };
          count++;
          if (count === promiseArr.length) {
            resolve(resultArr);
          }
        })
        .catch((err) => {
          resultArr[index] = { status: "rejected", val: err };
          count++;
          if (count === promiseArr.length) {
            resolve(resultArr);
          }
        });
    });
  });
};

resolve 和 reject

resolve 如果不涉及值的转换,那么基本上就是直接 resolve 一下,涉及值转换的话,主要区分 promise 实例和其他 reject 就更单纯了,直接 reject 包装一层完事

js
Promise.MyResolve = function (value) {
  // 以下情况为promise实例,直接返回
  if (value && typeof value === "object" && value instanceof Promise) {
    return value;
  }
  // 其他值需要手动包装一下
  return new Promise((resolve) => {
    resolve(value);
  });
};

Promise.MyReject = function (value) {
  return new Promise(_, (reject) => {
    reject(value);
  });
};