promise串行请求

679 阅读1分钟

在日常业务开发中,总会遇到这种场景,有一串请求,下一个请求总是依赖上一个请求的返回结果来决定是否继续发送请求,一般来说,我在处理这种场景的时候就是写async await 来处理,但是呢,本着能不写重复的代码就不写重复代码的原则(就是想写轮子),搞了一个小轮子

/**
 * @description 串行promise函数,将多个promise请求串联起来,下一个请求依赖于上一个请求的返回结果来决定是否发送请求
 */
export const serial = (queue) => {
  // 形参接受一个promise数组和一个回调
  // 校验所传参数
  const Yield = queue.find((i) => {
    return typeof i !== "object" && typeof i !== "function";
  });
  // 对所传参数做判断处理
  if (Yield) {
    throw new Error("所传参数不符合规范,请检查入参");
  }
  let res = [];
  let lock = false; // 锁
  return new Promise((resolve, reject) => {
    let dispatch = (nextRes) => {
      while (queue.length > 0 && !lock) {
        (async () => {
          lock = true;
          let p = queue.shift();
          let response = null;
          try {
            // 判断所传参数的类型
            switch (typeof p) {
              case "object":
                response = await p.promise(nextRes);
                break;
              case "function":
                response = await p(nextRes);
                break;
              default:
                break;
            }
            res.push(response);
            // 传入自己业务里的可以继续往下走的标准,返回布尔值
            let judge = p.judgement
              ? p.judgement && p.judgement(response)
              : true;
            if (!judge) {
              lock = true;
              return reject(res);
            }
            lock = false;
            // 全部的promise完成
            if (queue.length === 0 && !lock) {
              return resolve(res);
            }
            dispatch(response);
          } catch (error) {
            lock = true;
            res.push(error);
            reject(res);
          }
        })();
      }
    };
    dispatch();
  });
};

使用方式

serial([fn1, fn2, fn2, fn4]);
//或者使用更详细的
serial([
  {
    promise: fn1,
    judgement: (res) => {
      return true; // 根据当前的接口的返回结果来决定是否走下面的接口
    },
  },
  fn2,
  fn2,
  fn4,
]);