等等,Fetch 請求還能被取消?
回到2015年,當時的 fetch() 請求一旦發出,即便用戶已經切換頁面,它仍舊會持續消耗帶寬資源。
我們只能無奈嘆息,繼續工作。
直到 AbortController 的誕生——這個小巧而強大的 API,讓你可以隨時“拔掉電源”,中斷任何正在進行的網絡請求。
簡單總結:創建一個控制器,把它的 signal 傳給 fetch,完成后調用 controller.abort() 即可。
快速演示:30秒搞定
圖片
在瀏覽器開發者工具中運行示例代碼,打開網絡面板,你會看到請求變成灰色,瀏覽器內存也隨之減輕負擔,而你就像個魔法師一樣掌控請求。
真實場景示范:輸入即搜
想象一下這個經典用例:用戶輸入“ca”,你發起請求獲取貓的數據;
緊接著用戶輸入“cactus”,結果貓的數據先到,覆蓋了仙人掌的搜索結果。
這顯然是糟糕的用戶體驗。
現在,每一次按鍵都會快速取消前一個網絡請求,避免舊數據覆蓋新結果。
圖片
多個任務取消?一個控制器,多重信號
AbortController 并非只能用于 fetch。
任何接受 signal 的操作都能同步取消,比如 Web Streams、事件監聽器,甚至某些支持的第三方庫。
const ac = new AbortController();
// fetch 與超時控制合并使用
fetch('/big.json', { signal: ac.signal });
const timer = setTimeout(() => ac.abort(), 5000);
// 中止時同時取消滾動事件監聽
window.addEventListener('scroll', handle, { signal: ac.signal });
只需調用 ac.abort(),所有相關操作——fetch請求、定時器清理、事件監聽——統統停止。真正的“一鍵終止”。
瀏覽器兼容性
Safari 14 及以上,Chrome 66 以上,Firefox 57 以上,Edge 16 以上均已支持。
AbortController 取消請求時會拋出 AbortError,務必單獨捕獲,避免掩蓋其他異常。
控制器只能使用一次,調用 abort() 后需要重新創建新的實例。
這五行代碼就能幫你:
- 節省用戶寶貴的數據流量
- 避免請求競態引發的混亂
- 確保組件卸載時無內存泄漏
拿起你的控制器,輕松按下 abort,發布更流暢、高效的應用吧!