关于axios终止请求的思考

背景

Hello,everyone~

笔者前段时间面字节二面,面试官提出了一个问题是说,如果发出的请求在 10s 之内没有响应,我们应该怎么去取消这个请求。

我当时最先说了取消请求的 API 是 cancelToken 还有 AbortController,然后提出了两个思路,一个是新增标志位,在 cancelToken 里面设置时间,另一个是在 axios response 拦截器里面做处理。

然后面试官一直说这不够优雅,最后我还是没有答出来,最后告诉我可以用 Promise.race 来实现,接下来让我一个一个方案的来说:

方案一

使用cancelToken参数,axios自带cancelToken参数

学习链接

js 复制代码
this.axios({
     method: "post",
     url,
     data,
     cancelToken: new CancelToken(function executor(c) {
         cancel = c;
     }),
 })
 .then((response) => {
     clearTimeout(timer);
     if (!response.data.hasError) {
         this.$message.success("数据获取成功!");
         const results = response.data.result;
     } else {
         this.$message.error("数据获取失败!");
     }
 })
 .catch((error) => {
     clearTimeout(timer);
     if (error.response) {
         this.$message.error("数据获取失败!");
     }
 });

这里需要着重说一下 timer 和 cancel 的写法:

js 复制代码
const CancelToken = axios.CancelToken;
let cancel;
let timer = setTimeout(() => {
    cancel();
    this.$message.error("连接超时,请检查网络!")
}, 10000);

这里的核心逻辑就是存在一个包含 cancel 的 timer,无论是我收到了 result 还是发生了报错,我都会取消这个请求,但是如果说上面的两种行为都没有命中,那这个请求就会被 cancel 掉。

值得一提的是 setTimeout 肯定是存在误差的,这点我们没法去否认,就算我们使用第三种优雅的方式,我们依然会使用 setTimeout。

方案二

这个方式就是面试官强推的优雅的方式,我当时听到这个方式的时候还在疑惑可行性,后面重温了一下 Promise.race 之后,发现,这个真的太优雅了,具体的写法可以看看下面:

js 复制代码
function delayPromise(ms) {
    return new Promise(function (resolve) {
        setTimeout(resolve, ms);
    });
}
function timeoutPromise(promise, ms) {
    var timeout = delayPromise(ms).then(function () {
            throw new Error('Operation timed out after ' + ms + ' ms');
        });
    return Promise.race([promise, timeout]);
}

这里如果说我的 delay 时间是 10s,那我ms就设置为 10000,然后在两者之间发生竞速,如果说 promise 先执行了,那我就啥都不说,如果说 promise 是后执行的,那它就根本不会被执行了,用 Promise.race 取代了前面聊的笨笨的 API。优雅,太优雅了。

额外思考

写文章的时候,最开始是分成了三个方法,两个是前面写到的 cacelToken 和 Promice.race,其实还想到了一个最开始提到的axios拦截器,后来仔细的看了一下,我理解拦截器本身只是一个形式,我做请求的取消,既可以使用 cacelToken 这种 API,也可以使用 Promise.race 这种更为优雅的写法,核心的请求取消实现逻辑,还是在于前面的两种,拦截器也只是实现的位置不同罢了,所以这里就不做赘述。

那么这就是本篇文章的全部内容啦~

相关推荐
万少4 小时前
HarmonyOS 开发必会 5 种 Builder 详解
前端·harmonyos
哈里谢顿5 小时前
1000台裸金属并发创建中的重难点问题分析
面试
哈里谢顿5 小时前
20260303面试总结(全栈)
面试
橙序员小站6 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名8 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫9 小时前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊9 小时前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter9 小时前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
曲折9 小时前
Cesium-气象要素PNG色斑图叠加
前端·cesium
Forever7_9 小时前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js