發(fā)布于:2021-01-14 13:41:56
0
109
0
JavaScript的承諾一直是該語言的一大勝利——它們引發(fā)了一場異步編碼革命,極大地提高了web上的性能。native promise的一個缺點(diǎn)是沒有真正的方法來取消fetch…直到現(xiàn)在。JavaScript規(guī)范中添加了一個新的AbortController,它允許開發(fā)人員使用信號中止一個或多個fetch調(diào)用。
以下是取消取回調(diào)用的流程:
創(chuàng)建一個AbortController實(shí)例
該實(shí)例有一個signal屬性
將信號作為signal的獲取選項(xiàng)傳遞
調(diào)用AbortController的abort屬性取消所有使用該信號的讀取。
中止請求
以下是取消取回請求的基本框架:
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調(diào)用時發(fā)生AbortError,所以你可以通過比較錯誤名稱來監(jiān)聽在catch中中止的fetch:
}).catch(e => { if(e.name === "AbortError") { // We know it's been canceled! } });
將相同的信號傳遞給多個fetch調(diào)用將取消所有帶有該信號的請求:
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);
Jake Archibald在他的文章Abortable fetch中詳細(xì)介紹了一個很好的實(shí)用程序,它可以在不需要所有模板的情況下創(chuàng)建可Abortable fetch:
function abortableFetch(request, opts) { const controller = new AbortController(); const signal = controller.signal; return { abort: () => controller.abort(), ready: fetch(request, { ...opts, signal }) }; }
老實(shí)說,我對取消取回的方法不是很感興趣。在理想情況下,在fetch返回的Promise上使用一個基本的.cancel()是很酷的,但這也會帶來一些問題。無論如何,我對能夠取消fetch調(diào)用感到興奮,您也應(yīng)該如此!