【查漏補缺】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
來源:慕課網
本文首次發佈於慕課網 ,轉載請註明出處,謝謝合作

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