const delay = (mileSeconds = 2200) =>{
return new Promise((resolve) => {
setTimeout(() => {
resolve('')
}, mileSeconds)
})
}
const recursion = (promiseFun, resolve, reject, count, totalCount) => {
delay().then(() => {
promiseFun().then((res) => {
resolve(res)
}).catch(err => {
if(count >= totalCount) {
reject(err) // 持续调用失败,reject掉
return
}
// 调用失败,但是还没到重试次数,进入重试
recursion(promiseFun, resolve, reject, count+1, totalCount)
})
})
}
export const requestTry = (promiseFun, totalCount = 5) => {
return new Promise((resolve,reject) => {
let count = 1
promiseFun().then(res => {
resolve(res) // 一次调用成功,直接resolve
}).catch(err => {
if(totalCount <= 1) {
reject(err)// totalCount <= 1的情况下,就直接reject,就算是0,也至少请求1次
return
}
// 一次调用失败,但是还没到总调用次数就进入重试
recursion(promiseFun, resolve, reject, count +1, totalCount)
})
})
}
export default requestTry
delay()是延时函数,不用多说;recursion()是递归调用;requestTry是重试函数并且向外导出,接受2个参数,一个是promiseFun—具体执行接口调用的方法,一个是totalCount—重试次数,默认5次,返回Promise,方便后续操作。
最重要的是promiseFun方法如何写,得到想要的内容就resolve;调用失败,或者返回结果不是想要的,就reject掉,requestTry得到reject,会进入重试,重试次数达到了,不管结果如何,最终也会退出重试。
使用方法
使用vue-admin-template作为原始项目,直接用mock请求来试一下重试机制。dashboard页面增加一个按钮,调用getInfo请求。
import { getInfo } from '@/api/user'
import requestTry from '@/utils/retry'
export default {
methods: {
handleClick() {
requestTry(this.getData).then(res => {
console.log('res',res)
}).catche(err => {
console.log(err)
})
},
getData() { // promiseFun 方法
return new Promise((resolve,reject) => {
getInfo('admin-token').then(res => {
if(res.code === 20000){
resolve({success: true, data: res})
}else{
reject({success: false, data: res})
}
}).catch(err => {
reject({success: false, data: err})
})
})
}
}
}
requestTry(promiseFun,1),requestTry(promiseFun,0),只会调用一次接口
requestTry(promiseFun,3)最多会调用3次接口,totalCount默认为5。