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);
});
});
});