寫在前面
在網頁中,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
來源:慕課網
本文首次發佈於慕課網 ,轉載請註明出處,謝謝合作