如何在客户端终止一个已经发出的HTTP请求
Javascript 異步編程得益于 Promise 的實現(xiàn),它們極大地提高了Web開發(fā)的性能和體驗。不過原生的 Promise 有個最大的缺點就是一旦請求發(fā)出去,我們就無法取消它。但是我們找到了另一種方法來實現(xiàn)。
DOM 標準中添加了一個稱為 AbortController 的新的控制器,該控制器允許我們將其用作取消HTTP fetch 請求的信號。它利用 AbortSignal 屬性來執(zhí)行此操作。
它是在2017年添加的,并且在大多數(shù)瀏覽器中都支持(顯然,除了IE)。但是既然已經(jīng)拋棄對IE的支持,因此這真的是一件大事。
為什么我們需要取消 HTTP 請求?
在我們討論如何去取消之前,我們先了解下為什么需要取消 HTTP fetch 請求。當我們的應(yīng)用程序是由可以動態(tài)添加到 DOM 樹和從 DOM 樹刪除的多個組件組成的時候,許多組件都必須獨立進行相應(yīng)的HTTP請求。可能發(fā)生的情況是,在獲取請求完成之前,將其中一個組件卸載。這種情況多發(fā)生在網(wǎng)速慢的情況下,或者在頁面正在跳轉(zhuǎn)時用戶離開了該頁面。
由于請求是異步的,因此它將在后臺繼續(xù)執(zhí)行。并且如果處理不當,可能會導致一些錯誤。
谷歌瀏覽器的fetch請求默認超時時間是300秒,火狐瀏覽器是90秒。這些還都是在網(wǎng)絡(luò)正常的情況下。因此,如果需要的話,我們絕對希望通過自己的方式來終止HTTP的fetch請求。
AbortController和AbortSignal
AbortController和AbortSignal API是由DOM標準提供,這樣即使Web標準變化了它仍然可以繼續(xù)使用。我們來聲明一個控制器:
const controller = new AbortController();和一個signal常量
const signal = controller.signal;這個控制器僅僅只有一個abort方法。并且該方法一旦被觸發(fā),立即通知signal
controller.abort(); signal.addEventListener('abort', () => {console.log(signal.aborted); // true });如何取消一個HTTP fetch請求
fetch Api本身不允許以編程方式取消請求。但是它可以將AbortSignal作為參數(shù)。這樣一來,如果我們一旦需要,我們就可以在特定的時間段內(nèi)中止這個請求。
const controller = new AbortController(); const signal = controller.signal;fetch(url, { signal }).catch(err => {if (err.name === 'AbortError') {console.log('Fetch was aborted');}}); // Abort the request after 4s // aborts the fetch with 'AbortError' setTimeout(() => {controller.abort(); }, 4000);我們甚至可以自己封裝一個帶有延遲參數(shù)的fetch請求的函數(shù)
async function cancellableFetch(url, data, timeout = 4000) {const controller = new AbortController();const timer = setTimeout(() => controller.abort(), timeout);const response = await fetch(url, {...data,signal: controller.signal });clearTimeout(timer);return response; }值得注意的是:
如果我們將同一個signal傳遞給多個請求,如果一旦終止就取消了所有的請求。所以,它只能在如果一個請求失敗將取消所有請求的情況下使用。
由于控制器不能多次使用,如果我們不想在取消一個HTTP fetch請求時終止所有的請求,那么就需要為所有的控制器創(chuàng)建一個新的實例。
請求的取消僅發(fā)生在客戶端。盡管客戶端收不到響應(yīng),服務(wù)器仍可能會對其進行處理。
我們也可以使用Promise.race來實現(xiàn)此功能,但是該解決方案會使請求掛起而不是中止請求。它將繼續(xù)在后臺消耗帶寬。
以上就是在耗時終止HTTP fetch 請求的方法,不知道有沒有疑問,歡迎留言!
總結(jié)
以上是生活随笔為你收集整理的如何在客户端终止一个已经发出的HTTP请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 仅使用HTML和CSS实现的标签云效果
- 下一篇: 【超详细教程】如何使用TypeScrip