爲何寫這個題目呢?
由於以前寫的一個 Node 程序有點小問題,使用的 axios 經過代理請求數據,代理服務器(阿布雲)時不時抽風(40七、41三、503)。前端
由於第一次寫的時候當作一個 DEMO 去實現的,寫的挺簡陋,只能說大致功能對,可是沒有容錯機制。ios
這裏咱們先算一筆賬啊,一次請求等於 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)
我直接在 data
上增長一個 __try_count
用於設置重試次數。併發
由於 Axios 是支持 Promise,因此咱們的方法也支持。
axios 若是成功了咱們也 resolve。
axios 若是失敗了咱們先判斷次數,而後根據具體的錯誤,進行重試。cors
ECONNABORTED
很奇怪好好的資源他也不加載就卡住了,因此我設置了 timeoutECONNRESET
也是一個很奇怪的錯誤。(既然是 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) }) }) }
歡迎你們關注個人公衆號。有疑問也能夠加個人微信前端交流羣。dom