LiesAuer's Blog
关于
归档
友链
猫咪
RSS
切换模式
返回顶部
首页
说说
日常
开发
游戏
资源
虚拟货币
LiesAuer's Blog
首页
说说
日常
开发
游戏
资源
虚拟货币
关于
归档
友链
猫咪
RSS
axios较完美的超时以及重试失败解决方案
开发
·
2020-01-06
LiesAuer
## 代码引用 1. [Retry Solution From KyleRoss@github](https://github.com/axios/axios/issues/164#issuecomment-327837467 "Retry Solution From KyleRoss@github") 2. [Timeout Solution From aarcangeli@github](https://github.com/axios/axios/issues/2143#issuecomment-495994940 "Timeout Solution From aarcangeli@github") ## axios 的 retry 解决方案 见:[Retry Solution From KyleRoss@github](https://github.com/axios/axios/issues/164#issuecomment-327837467 "Retry Solution From KyleRoss@github") ## axios 的 timeout 问题 在`0.18.0`版本中`axios`的`timeout`并没有被正确实现导致有可能在弱网环境或不稳定环境或代理环境下`timeout`无效、程序卡住的情况(见:[Axios will not timeout on idle sockets](https://github.com/axios/axios/issues/2143 "Axios will not timeout on idle sockets")),虽然这问题在`0.19.0`版本中修复了,但是`0.19.0`版本中对配置合并的规则的阻断性更新导致我们的重试失败解决方案失效(见:[Axios 0.19.0 issue](https://github.com/axios/axios/issues/2397 "Axios 0.19.0 issue")),所以我们无法升级到`0.19.0`来解决这个问题。 ## 用 CancelToken 替代 timeout 根据 [@aarcangeli](https://github.com/aarcangeli "@aarcangeli") 提供的 [CancelToken 代替方案](https://github.com/axios/axios/issues/2143#issuecomment-495994940 "CancelToken 代替方案"),我们可以很轻松的解决上面所述的 timeout 问题。 ```js const CancelToken = axios.CancelToken; const source = CancelToken.source(); let timeout = setTimeout(() => source.cancel('Timeout'), 5000); axios.get('http://localhost:3000', { timeout: 1000, cancelToken: source.token }) .then(() => { clearTimeout(timeout); console.log('hello there') }); ``` ## 最终解决方案 ```js const axios = require('axios'); timeout = 10000; // BUG: https://github.com/axios/axios/issues/2143 // axios.defaults.timeout = timeout; axios.defaults.retry = 3; axios.defaults.retryDelay = 1000; function axiosRetryInterceptor(err) { var message, config; if (axios.isCancel(err)) { message = err.message.message; config = err.message.config; } else { message = err.message; config = err.config; } config.clearCancelToken(); // If config does not exist or the retry option is not set, reject if(!config || !config.retry) return Promise.reject(new Error(message)); // Set the variable for keeping track of the retry count config.__retryCount = config.__retryCount || 0; // Check if we've maxed out the total number of retries if(config.__retryCount >= config.retry) { // Reject with the error return Promise.reject(new Error(message)); } // Increase the retry count config.__retryCount += 1; // Create new promise to handle exponential backoff var backoff = new Promise(function(resolve) { setTimeout(function() { resolve(); }, config.retryDelay || 1); }); // Return the promise in which recalls axios to retry the request return backoff.then(function() { console.log(`请求失败,重试中:${config.url}`); return axios(config); }); } axios.interceptors.request.use(function (config) { const CancelToken = axios.CancelToken; const source = CancelToken.source(); let token = setTimeout(() => source.cancel({message:'Timeout', config: config}), timeout); config.cancelToken = source.token; config.clearCancelToken = () => clearTimeout(token); return config; }); axios.interceptors.response.use(function (response){ response.config.clearCancelToken(); return response; }, axiosRetryInterceptor); axios.get("https://example.com/").then(response => { console.log(response.data); }, error => console.log(error)); ``` ## 注意事项 `npm install`时请指定`axios`版本为`0.18.0`,因为上面的代码针对的都是`0.18.0`版本的`axios`。 ```shell npm install axios@0.18.0 --save ```
取消回复
提交评论
33
2021-06-29
回复
232
热门文章
HumanMod - 免费的集N多功能于一身的HFF(人类一败涂地)插件
记抖音爬虫中所遇到的坑
设置网易邮箱大师为Win10默认邮件客户端
微信表情包工具【2023/05/04】更新
更改TLY本地代理端口
让Tauri前端部分调试如调试常规Web项目般丝滑
使用 v2rayN + SSTap 对 Win10 + WSL2 进行超简单易用的科学上网设置
最新评论
Jekanius: Hello, I implemented such a mech...
Jekanius: I need you help.
Jekanius: Is it working now?
任情随缘: 很多站长卖的站和老域名大部分都到了这些搞灰产的手里。
滚石: 赞
阿大萨瓦: 群满了
指南: 不换一个主题吗
关于站长
广东佛山
liesauer#liesauer.net
LiesAuer
粤ICP备16094588号-1
Theme
Jasmine
by
Kent Liao
232