为何写这个题目呢?
由于以前写的一个 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