作者:David Walsh
翻譯:瘋狂的技術宅
原文:https://davidwalsh.name/cancel-fetch
未經允許嚴禁轉載
JavaScript 的 promise一直是該語言的一大勝利——它們引發了異步編程的革命,極大地改善了 Web 性能。原生 promise 的一個缺點是,到目前爲止,還沒有可以取消 fetch
的真正方法。 JavaScript 規範中添加了新的 AbortController
,允許開發人員使用信號中止一個或多個 fetch
調用。
以下是取消 fetch
調用的工作流程:
- 創建一個
AbortController
實例 - 該實例具有
signal
屬性 - 將
signal
傳遞給 fetch option 的signal
- 調用
AbortController
的abort
屬性來取消所有使用該信號的 fetch。
中止 Fetch
以下是取消 Fetch 請求的基本步驟:
const controller = new AbortController();
const { signal } = controller;
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 1 is complete!`);
}).catch(e => {
console.warn(`Fetch 1 error: ${e.message}`);
});
// Abort request
controller.abort();
在 abort
調用時發生 AbortError
,因此你可以通過比較錯誤名稱來偵聽 catch
中的中止操作。
}).catch(e => {
if(e.name === "AbortError") {
// We know it's been canceled!
}
});
將相同的信號傳遞給多個 fetch
調用將會取消該信號的所有請求:
const controller = new AbortController();
const { signal } = controller;
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 1 is complete!`);
}).catch(e => {
console.warn(`Fetch 1 error: ${e.message}`);
});
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 2 is complete!`);
}).catch(e => {
console.warn(`Fetch 2 error: ${e.message}`);
});
// Wait 2 seconds to abort both requests
setTimeout(() => controller.abort(), 2000);
傑克·阿奇博爾德(Jack Archibald)在他的文章 Abortable fetch 中,詳細介紹了一個很好的應用,它能夠用於創建可中止的 Fetch,而無需所有樣板:
function abortableFetch(request, opts) {
const controller = new AbortController();
const signal = controller.signal;
return {
abort: () => controller.abort(),
ready: fetch(request, { ...opts, signal })
};
}
說實話,我對取消 Fetch 的方法並不感到興奮。在理想的世界中,通過 Fetch 返回的 Promise 中的 .cancel()
會很酷,但是也會帶來一些問題。無論如何,我爲能夠取消 Fetch
調用而感到高興,你也應該如此!
歡迎關注微信公衆號:前端先鋒,每天第一時間閱讀最新技術文章。