axios是前端常用的http请求库,在业务中希望增加重试功能,本来通过自己简单的封装也能实现这个功能,详见我以前的帖子,本着杀鸡用牛刀的精神通过RxJs为axios增加这个功能
未改造前的函数
import axios from 'axios'
const get = (url, data) => {
return axios.get(url, { params: data })
}
改造后
import axios from 'axios'
import { defer } from 'rxjs'
import { retry } from 'rxjs/operators';
const get = (url, data) => {
return new Promise((resolve,reject)=>{
defer(() => axios.get(url, { params: data }))
.pipe(retry(3))
.subscribe({next: resolve,error: reject})
})
}
调用测试
get('./data.json',{a:1}).then(res=>{
console.log('then',res)
}).catch(res=>{
console.log('catch',res)
})
测试结果
异常测试(data2.json不存在)
get('./data2.json',{a:1}).then(res=>{
console.log('then',res)
}).catch(res=>{
console.log('catch',res)
})
测试结果
上面是出现错误后简单的重试,往往在实际项目中我们不希望出错后立刻重试,如果能延时一小段时间再重试就好了,下面再改进一下支持延时重试
import axios from 'axios'
import { defer } from 'rxjs'
import { retryWhen,delay,take } from 'rxjs/operators'
const get = (url, data) => {
return new Promise((resolve,reject)=>{
defer(() => axios.get(url, { params: data }))
.pipe(retryWhen(errors => errors.pipe(delay(3000),take(3))))
.subscribe({next: resolve,error: reject})
})
}
测试结果,通过时间瀑布可以看到延时效果
上面的延迟重试实现了,但是有个问题,异常信息不会输出出来,也就是get的catch方法不会执行,因此还需要再此改进
import axios from 'axios'
import { defer } from 'rxjs'
import { retryWhen,delay,scan } from 'rxjs/operators'
const get = (url, data) => {
return new Promise((resolve,reject)=>{
defer(() => axios.get(url, { params: data }))
.pipe(retryWhen(errors =>errors.pipe(scan((count,err)=>{
if(count>3)throw new Error(err)
return count+1
},0),delay(3000))
))
.subscribe({next: resolve,error: reject})
})
}
再次测试,发现异常信息又可以正常输出了