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

写在前面

在网页中,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如下:

https://www.npmjs.com/package/abort-controller

https://www.npmjs.com/package/abortcontroller-polyfill

写在后面

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

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

https://github.com/misaka-ink/fetch2


作者:Coy_Pan
链接:http://www.imooc.com/article/301334
来源:慕课网
本文首次发布于慕课网 ,转载请注明出处,谢谢合作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章