在用戶交互或者最新輸入的時候,你經常須要在一個 web 應用中頻繁發起請求。好比說在輸入文字的時候的自動完成操做或者是在地圖上放大縮小的操做。讓咱們花一點時間去思考一下這些例子。首先是自動完成,每一次咱們輸入的時候(或者更少在用 debounce 時)咱們就會發出一個請求。若是用戶輸入改變的時候,舊的請求就會與如今無關,當咱們持續打字輸入的時候(好比 「java」 和 「javascript」 )。也許有不少冗餘請求,在咱們拿到咱們須要的東西的時候。javascript
而後是地圖的例子。咱們在縮放查看地圖的時候,咱們對於以前縮放級別的圖塊再也不感興趣。與此同時,爲了冗餘數據,許多請求還處於等待。前端
帶着咱們第一個例子,看看實現一個自動完成場景的原生代碼。爲了本文的目的,咱們將使用更現代的 fetch 而不是 XMLHttpRequest 來提出網絡請求。 代碼以下:java
autocompleteInput.addEventListener('keydown', function() {
const url = "https://api.example.com/autocomplete"
fetch(url)
.then((response) => {
// Do something with the response
updateAutocompleteMenu()
})
.catch((error) => {
// Something went wrong
handleAutocompleteError(error);
})
});
複製代碼
這個例子的問題就是每個請求都要完成,即便它再也不相關。咱們能夠實現一個額外的邏輯在 updateAutocompeleteMenu 中去防止額外的代碼,可是卻不能真正中止這個請求。值得注意的是,瀏覽器有同時請求的限制,這意味着一旦限制被觸發時,請求將隊列化(並且每一個瀏覽器限制又不一樣)。git
咱們能夠用來解決上述問題的新瀏覽器技術是 Abortable Fetch 。 Abortable Fetch 依賴瀏覽器的規範 AbortController 。這個控制器有 signal 屬性,咱們用它傳遞,在以後的時機中用控制器中斷方法去取消請求。github
一個例子以下:web
autocompleteInput.addEventListener('keydown', function() {
const url = "https://api.example.com/autocomplete"
let controller;
let signal;
autocompleteInput.addEventListener('keyup', () => {
if (controller !== undefined) {
// Cancel the previous request
controller.abort();
}
// Feature detect
if ("AbortController" in window) {
controller = new AbortController;
signal = controller.signal;
}
// Pass the signal to the fetch request
fetch(url, {signal})
.then((response) => {
// Do something with the response
updateAutocompleteMenu()
})
.catch((error) => {
// Something went wrong
handleAutocompleteError(error);
})
});
});
複製代碼
咱們進行特性檢測,以肯定咱們是否可使用 AbortController (它在 Edge,Firefox,Opera 和 Chrome 66 中支持!)。咱們確認是否有一個控制器已經建立,若是是,咱們調用 controller.abort() 去取消以前的請求。你也能夠一次用相同的 signal 取消多個 fetches 。api
我建立了一個展現如何使用 Abortable Fetch 小例子,基於自動完成場景的想法(沒有任何實現細節!)。去理解每當輸入網絡請求時會發生什麼。 若是您在舊請求完成以前進行了新的輸入,它將停止先前的抓取。 在實踐中它看起來有點像這樣:promise
源代碼瀏覽器
也許 AbortController 最酷的部分是它被設計成一個停止異步任務的通用機制。它是 WHATWG specification 的一部分。這意味着它是DOM規範而不是語言(ECMAScript)規範,但對於前端開發來講,這仍然是一個有用的功能。你能夠利用它做爲一個更清晰的異步控制流機制,用於實現異步任務的時候(即當使用 Promises 時)。這篇Bram Van Damme super article for a more detailed example 文章會有更多我所講述的細節。網絡
本翻譯自原文 - Cancelling Requests with Abortable Fetch。不按期更新技術博文歡迎star。因爲本人水平有限,錯誤之處在所不免,敬請指正!轉載請註明出處,保留原文連接以及做者信息。