retry(pf,{
times: 3,
//每次延迟
delay: 1000,
//每次延迟增量
increment: 1000,
shouldRetry: (err,opts) => {
//判断是否应该继续
return true;
},
onRetry: (data) => {
//收集error和次数信息
}
})
.then(data => console.log(data))
.catch(err => console.log(err));
//then链实现
function retry(promiseGen,opts){
return promiseGen().catch(err => {
if(opts.shouldRetry && !opts.shouldRetry(err,opts)) return Promise.reject(err);
if(opts.times-- < 1) return Promise.reject(err);
let starter = opts.delay ? delay(opts.delay) : Promise.resolve();
return starter.then((res) => {
if(opts.onRetry) opts.onRetry({err,times:opts.times});
opts.delay += opts.increment || 0;
return retry(promiseGen,opts);
})
})
}
//await实现,使用await可以直接在for循环中操作,非常清晰
async function retry(promiseGen,opts){
let res,err;
let errors = [];
let starter = Promise.resolve();
for(var i=0;i<=opts.times;i++){
try{
res = await starter.then(promiseGen);
}
catch(e){
err = e;
}
if(!err) return Promise.resolve(res);
errors[i] = err;
err = null;
if(opts.delay) {
starter = delay(opts.delay);
opts.delay += opts.increment || 0;
}
}
return Promise.reject({errors,times:i})
}
function delay(time){
return new Promise(resolve => setTimeout(resolve, time))
}