1

使用AbortController abort中断原生fetch或axios请求

 1 year ago
source link: https://www.zhangxinxu.com/wordpress/2023/01/fetch-abortcontroller-abort-fetch-axios/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10694 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

占位图

一、AbortController的作用

AbortController可以用来终止一个或多个Web请求。

我大致看了下,此API可以终止fetch请求,任意响应主体和流。

日常开发,用的最多的就是对 fetch 请求的终止,由于axios(知名HTTP 库,基于promise,可以用在浏览器和node.js 中)的底层是使用fetch实现的,因此,AbortController也能用来终止axios发送的请求。

使用的时候先构造。

controller = new AbortController();

支持一个属性和一个方法:

AbortController.signal 返回AbortSignal对象,这个对象需要设置在fetch请求中,这样我们就可以在外部终止这个请求了。相当于在fetch请求内部嵌入一个抓手,或者说预埋一个开关。

具体如何使用参见下一节的案例和代码示意。

AbortController.abort() 终止请求的方法。只要请求还没有完成,都是可以终止的。

二、中断请求示意

眼见为实,具体如何使用,还需要demo出马。

您可以狠狠地点击这里:AbortController取消fetch请求demo

下图GIF是演示示意,我们快速点击页面中的几个按钮,一定是显示最后一个按钮点击对应的返回数据。

例如,依次点击”zhang”, “xin”, “xu” 三个按钮,返回值是 ‘xu’:

点击按钮与返回值示意

此时打开浏览器控制台,查看network网络请求,可以看到前面两个按钮的请求被终止取消了,如下截图所示:

请求被取消示意

逻辑实现的核心代码如下所示,即,如果请求执行的时候,发现上一个请求还没完成,就abort阻止,同时,创建新的AbortController中断对象。

const data = {};
// 构造器对象
let conrtoller = null;

// 按钮点击
button.addEventListener('click', function (event) {
  // 构造 AbortController 对象
  if (data.conrtoller) {
    conrtoller = data.conrtoller;
  } else {
    conrtoller = new AbortController();
    data.conrtoller = conrtoller;
  }
  // 如果正在请求,终止
  if (data.loading) {
    conrtoller.abort();

    // 构建新的 AbortController
    conrtoller = new AbortController();
    data.conrtoller = conrtoller;
  }

  data.loading = true;

  // 请求逻辑
  fetch('./getVal.php?val=' + event.target.value, {
    signal: conrtoller.signal
  }).then(res => res.text()).then(text => {
    // text 就是返回内容
  });
});

上面代码不算完美,多次new构造其实并不需要,不过好在能够解决问题。

如果是在axios中?

如果项目用的是axios,则用法其实是类似的,使用示意:

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// 取消当前请求
controller.abort()

万变不离其宗,大家若是遇到类似需求,也可以按照上面的骨架进行处理。

AbortControllerAbortSignal所有现代浏览器均支持,我看了下,应该是2018年开始支持的,算算到现在,应该可以在正式环境中使用了。

如果不放心,还可以再引入一段polyfill兼容低版本的浏览器,见这个项目:https://github.com/mo/abortcontroller-polyfill

AbortController兼容性

三、春节快乐

这应该是春节前的最后一篇了,还有一篇写了一半,没时间更新了,因为明天下午就会回老家了,我要去钓鱼了,嘿嘿。

现在总算来去自由了。

2022年一晃就过去了,这一周周的,越年长,时间过得越快。

来年继续加油吧,钓鱼技术可以进一步提高,我觉得明年会是钓鱼水平长足进步的一年。

如果本文内容你觉得有所学,欢迎转发,欢迎分享。

😋😋😋

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK