继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【查漏补缺】fetch是可以取消的

Coy_Pan
关注TA
已关注
手记 25
粉丝 12
获赞 119

ID: 符合预期的CoyPan
CoyPan,BAT某厂符合预期的FE,正努力成为一名出色的工程师

写在前面

在网页中,Ajax和Fetch是最常用的发起网络请求的两种方式。在面试中,关于这两者的区别也会被提及。你也许听说过这么一个说法,Ajax是可以取消的,Fetch是不可以取消的。真的是这样吗?

取消Ajax

使用ajax发起一个网络请求的代码大致如下:

var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = function(){};
xhr.send();

想要中断这个ajax请求,直接调用

xhr.abort()

图片描述

取消fetch

使用fetch发起一个网络请求的代码大致如下:

fetch(url)
    .then(r => r.json())
    .then(response => {

    })
    .catch(err => {
        console.error("Error in fetching!", err);
    });

fetch是基于promise的,可以在页面主线程、worker等地方使用,十分的方便。

想取消一个fetch请求,可以使用AbortController.

AbortController代表一个控制器对象,允许你在需要时中止一个或多个DOM请求。直接来看示例代码:

var controller = new AbortController();
var signal = controller.signal;

// 将signal传入fetch的第二个参数
fetch(url, { signal }) 
  .then(function(response) {
    ...
  }).catch(function(err) {
    if (err.name === 'AbortError') {
      console.log('Fetch was aborted');
    } else {
      console.error('Oops!', err);
    }
  });
  
setTimeout(() => {
  controller.abort(); // 取消fetch请求
}, 1000);

图片描述

当我们主动取消fetch时,fetch的promise 会 reject 以下错误:

new DOMException('Aborted', 'AbortError')

这个时候,会进入fecth的catch逻辑块。

当然,如果fetch已经resolve了,我们就无法取消fetch了。

AbortController 当前的兼容性如下:

图片描述

polyfills如下:

写在后面

取消网络请求是一个很重要的点,特别是在页面中有大量请求,而用户切到其他页面时,适当的取消pending中的网络请求,可以减少网络资源的浪费和页面卡顿,提升用户体验。fetch,也是可以取消的。

最后,推荐一个不错的fetch库:

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP