在前端開發中,取消網絡請求是一個常見的需求,尤其是在用戶頻繁操作或需要中斷長時間請求的場景下。
AbortController?主要用于 ?優雅地管理和取消異步操作:
瀏覽器原生 API
一、代碼解析
1. ?創建 AbortController 實例
const controller = new AbortController();
- 作用:實例化一個?
AbortController
?對象,用于生成?AbortSignal
?信號對象。 - ?返回值:
controller
?包含兩個屬性:signal
:用于傳遞給支持取消的 API的信號對象abort()
:調用此方法會觸發信號的中止邏輯
2. ?發起可取消的 fetch 請求
fetch(url, { signal }).then(response => response.json()).catch(error => {if (error.name === 'AbortError') {console.log('請求已取消');}});
關鍵點:
- 將?
controller.signal
?作為?fetch
?的第二個參數傳入,使請求與信號關聯 - 當?
controller.abort()
?被調用時,fetch
?請求會檢測到?signal.aborted
?為?true
,終止請求并拋出?AbortError
- ?錯誤處理:通過?
catch
?捕獲錯誤,判斷?error.name === 'AbortError'
?以區分請求是否被主動取消
3. ?終止請求
controller.abort(); // 終止請求
原理==信號機制==:
AbortController
?通過?signal
?對象實現跨 API 的取消信號傳遞- 當?
abort()
?被調用時,所有關聯的?signal
?會觸發?abort
?事件,通知相關操作終止
一、核心應用場景
1.?取消網絡請求
在用戶頻繁操作(如快速切換頁面、重復提交表單)時,避免因多個未完成的請求導致 ?競態條件
示例:用戶連續點擊“加載數據”按鈕時,僅保留最后一次請求的結果,中斷之前的請求
const controller = new AbortController();
fetch(url, { signal }).then(response => response.json()).catch(error => {if (error.name === 'AbortError') {console.log('請求已取消');}});
controller.abort(); // 終止請求
2.超時控制
結合?AbortSignal.timeout()
?自動終止超時請求,避免長時間等待無響應的接口?
fetch('/api/data', { signal: AbortSignal.timeout(5000) }) // 5秒超時.then(response => response.json()).catch(error => {if (error.name === 'TimeoutError') {console.log('請求超時');}});
二、實際應用場景
1.?搜索框防抖取消
用戶連續輸入時,僅保留最后一次請求
const search = debounce(async (query) => {if (controller.value) controller.value.abort();controller.value = new AbortController();const response = await fetch(`/api/search?q=${query}`, { signal: controller.value.signal });// 更新搜索結果
}, 300);
2.分頁加載控制
切換分頁時取消上一頁請求:
const loadPage = async (page) => {if (controller.value) controller.value.abort();controller.value = new AbortController();const data = await fetch(`/api/data?page=${page}`, { signal: controller.value.signal });// 渲染新數據
};
三、技術優勢
- 統一控制流
通過單一?AbortController
?實例管理多個異步操作,簡化代碼邏輯? - ?避免資源浪費
及時終止無效請求,減少網絡帶寬和服務器壓力? - ?兼容性適配
現代瀏覽器廣泛支持,低版本環境可通過 Polyfill 兼容?