实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject

1,976 阅读1分钟

1、代码实现

这一题整体难度不大,只需要实现一个循环就好啦。

第一反应是写个递归,但是这个是基于Promise的扩展,就想到了async,这样实现代码可读性更好。

// 传入一个promise生成器
Promise.retry = async (promiseFunc, maxTimes = 3) => {
  let result;
  while (maxTimes > 0) {
    --maxTimes;
    // 新建一个promise接管目标promise的resolve以及reject
    await new Promise((res, rej) => {
      promiseFunc()
        .then((result1) => {
          // 成功即可终端循环
          maxTimes = 0;
          result = result1;
          res();
        })
        .catch((e) => {
          // 失败检测是否还有重试次数
          if (maxTimes === 0) {
            rej(e);
          } else {
            res();
          }
        });
    });
  }
  return result;
};

2、代码测试

describe("实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject", () => {
  test("全部失败", () => {
    let testFunc = jest.fn(() => Promise.reject());
    Promise.retry(testFunc).catch((e) => {
      expect(testFunc).toHaveBeenCalledTimes(3);
    });
  });
  test("2次成功", () => {
    let time = 0;
    let testFunc = jest.fn(() =>
      ++time < 2 ? Promise.reject() : Promise.resolve()
    );
    return Promise.retry(testFunc).then(() => {
      expect(testFunc).toHaveBeenCalledTimes(2);
    });
  });
});