封裝 axios 實現自動重試
阿新 • • 發佈:2020-09-13
為什麼寫這個題目呢?
因為之前寫的一個 Node 程式有點小問題,使用的 axios 通過代理請求資料,代理伺服器(阿布雲)時不時抽風(407、413、503)。
因為第一次寫的時候當做一個 DEMO 去實現的,寫的挺簡陋,只能說大體功能對,但是沒有容錯機制。
這裡我們先算一筆帳啊,一次請求等於 1+100 次,因為我內部還會請求好多資料。
如果只是第一次失敗了,那麼無關緊要,大不了重發一次。
但是如果是後面 100 次中有極個別暴雷了,那麼就會導致整個101次請求全部作廢。(因為返回的資料是錯誤的,使用者會觸發第二次請求。不止加重了伺服器的壓力,還增加了使用者檢查的壓力)
好了,為什麼實現這個功能說了,那麼我們要開始實現了。
axios 發起請求
axios 發請求還是很簡單的,那麼我們可以直接仿照他來實現一下封裝。
axios({
url: 'https://www.lilnong.top/cors/axiosAutoTry',
params: 'user=sf',
method: 'get'
})
.then(console.log)
.catch(console.log)
廣州vi設計公司 http://www.maiqicn.com 我的007辦公資源網 https://www.wode007.com
實現自動重試
我直接在data上增加一個__try_count用於設定重試次數。
因為 Axios 是支援 Promise,所以我們的方法也支援。
axios 如果失敗了我們先判斷次數,然後根據具體的錯誤,進行重試。
- 407 就是我理解的抽風
- 413 是請求併發太高,為了不佔用多少可以加個延時器。
- 503 也是我理解的抽風
- ECONNABORTED很奇怪好好的資源他也不載入就卡住了,所以我設定了 timeout
- ECONNRESET也是一個很奇怪的錯誤。(既然是 Node,我理解他經常出錯誤。)
function axiosAutoTry(data){
return new Promise((resolve, reject)=>{
axios(data)
.then((data)=>{
resolve(data)
})
.catch(error=>{
// 有重試次數
if(typeof data.__try_count == 'number' && data.__try_count>0){
console.error('重試請求', error.message, data)
data.__try_count--;
if(error.code == 'ECONNABORTED'){
// 中止,超時
return resolve(axiosAutoTry(data))
}else if(error.code == 'ECONNRESET'){
//
return resolve(axiosAutoTry(data))
}else{
if(error.response && error.response.status == 407){
// 代理407
return setTimeout(v=>{
resolve(axiosAutoTry(data))
}, 500 + Math.random() * 500)
}else if(error.response && error.response.status == 503){
// 伺服器異常
return setTimeout(v=>{
resolve(axiosAutoTry(data))
}, 1000 + Math.random() * 500)
}else if(error.response && error.response.status == 429){
// 併發超過限制
return setTimeout(v=>{
resolve(axiosAutoTry(data))
}, 1000 + Math.random() * 1000)
}
// console.error('異常錯誤', error)
}
}
reject(error)
})
})
}