// Round 1
// time: 21:26 - 21:44
// 默认最多尝试 3 次, 每次用时递减
// 缺点: 每次用时多少并不知道
// 失败: setTimeout 那里并没有 resolve, reject
function requestWithRetry(url, attempts = 3) {
const attemptsLeft = attempts - 1;
const maxDelayMS = 30000; // 30 seconds
const minDelayMS = 3000; // 3 seconds
let nextDelayMS = maxDelayMS; // 30 seconds
if (attempts * minDelayMS < maxDelayMS) {
nextDelayMS = maxDelayMS - attempts * minDelayMS;
}
console.log(new Date().toLocaleTimeString())
return fetch(url)
.then((res) => res.json())
.catch((err) => {
if (attempts === 0) {
throw err
}
setTimeout(() => {
requestWithRetry(url, attemptsLeft);
}, nextDelayMS);
});
}
// 写错 url, 为触发报错, 正确 url 为 https://reqbin.com/echo/get/json
requestWithRetry("https://reqbin.com/echo/get/jsons", 3).then(
(response) => console.log(response),
(error) => console.log('ha')
);
// ---
// Round 2
// time: 21:46 - 23:06
// 结果: 运行正常, 当前示例共发起 4 次请求, 每次在之前的延迟上加 3 秒, 最大 30 秒延迟.
function requestWithRetry(url, attempts = 3, attempted = 0) {
const maxDelayMS = 30000; // delay 30 seconds at most
const minDelayMS = 3000; // delay 3 seconds at least
let nextDelayMS = minDelayMS * attempted || minDelayMS;
if (nextDelayMS >= maxDelayMS) {
nextDelayMS = maxDelayMS;
}
console.log("attempted", attempted);
console.log('time', new Date().toLocaleTimeString());
console.log('nextDelayMS', nextDelayMS);
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => res.json())
.then((res) => resolve(res))
.catch((err) => {
if (attempted >= attempts) {
reject(err);
return;
}
setTimeout(() => {
resolve(requestWithRetry(url, attempts, attempted + 1));
}, nextDelayMS);
});
});
}
// 写错 url, 为触发报错, 正确 url 为 https://reqbin.com/echo/get/json
requestWithRetry("https://reqbin.com/echo/get/jsons", 10).then(
(response) => console.log('success', response),
(error) => {
console.log("error", error);
}
);