js中AbortController請(qǐng)求中止的實(shí)現(xiàn)
一、介紹
AbortController 是 JavaScript 提供的一個(gè)強(qiáng)大工具,它允許開發(fā)者中止一個(gè)或多個(gè) Web 請(qǐng)求。這個(gè) API 最初是為了 fetch 請(qǐng)求設(shè)計(jì)的,但現(xiàn)在已經(jīng)被許多其他瀏覽器 API 和第三方庫所采用。
AbortController 的主要用途包括
- 取消不再需要的
fetch請(qǐng)求; - 清理長(zhǎng)時(shí)間運(yùn)行的操作;
- 實(shí)現(xiàn)請(qǐng)求超時(shí);
- 處理組件卸載時(shí)的資源清理;
二、基本使用
2.1 創(chuàng)建 AbortController
const controller = new AbortController(); const signal = controller.signal;
2.2 與 fetch 結(jié)合使用
const controller = new AbortController();
const signal = controller.signal;
fetch("https://api.example.com/data", { signal })
.then((response) => response.json())
.then((data) => console.log(data))
.catch((err) => {
if (err.name === "AbortError") {
console.log("請(qǐng)求被中止");
} else {
console.error("請(qǐng)求錯(cuò)誤:", err);
}
});
// 在需要時(shí)中止請(qǐng)求
controller.abort();
三、常用場(chǎng)景
3.1 用戶觸發(fā)的取消
const controller = new AbortController();
const fetchButton = document.getElementById("fetch-button");
const cancelButton = document.getElementById("cancel-button");
fetchButton.addEventListener("click", () => {
fetch("https://api.example.com/data", { signal: controller.signal }).then(/* ... */).catch(/* ... */);
});
cancelButton.addEventListener("click", () => {
controller.abort();
});
3.2 請(qǐng)求超時(shí)
function fetchWithTimeout(url, options, timeout = 5000) {
const controller = new AbortController();
const signal = controller.signal;
// 設(shè)置超時(shí)
const timeoutId = setTimeout(() => controller.abort(), timeout);
return fetch(url, { ...options, signal }).finally(() => clearTimeout(timeoutId));
}
fetchWithTimeout("https://api.example.com/data", {}, 3000)
.then(/* ... */)
.catch((err) => {
if (err.name === "AbortError") {
console.log("請(qǐng)求超時(shí)");
}
});
3.3 React 組件卸載時(shí)取消請(qǐng)求
import { useEffect, useState } from "react";
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
const controller = new AbortController();
fetch("https://api.example.com/data", { signal: controller.signal })
.then((response) => response.json())
.then(setData)
.catch((err) => {
if (err.name !== "AbortError") {
console.error("獲取數(shù)據(jù)失敗:", err);
}
});
return () => controller.abort();
}, []);
return <div>{data ? JSON.stringify(data) : "加載中..."}</div>;
}
3.4 并行請(qǐng)求的統(tǒng)一取消
const controller = new AbortController();
const signal = controller.signal;
const requests = [fetch("/api/data1", { signal }), fetch("/api/data2", { signal }), fetch("/api/data3", { signal })];
Promise.all(requests)
.then(/* 處理所有響應(yīng) */)
.catch((err) => {
if (err.name === "AbortError") {
console.log("所有請(qǐng)求已被取消");
}
});
// 取消所有請(qǐng)求
controller.abort();
四、高級(jí)細(xì)節(jié)
4.1 信號(hào)狀態(tài)
signal.aborted 屬性可以檢查信號(hào)是否已被中止:
const controller = new AbortController(); console.log(controller.signal.aborted); // false controller.abort(); console.log(controller.signal.aborted); // true
4.2 事件監(jiān)聽
可以監(jiān)聽 abort 事件:
const controller = new AbortController();
controller.signal.addEventListener("abort", () => {
console.log("請(qǐng)求被中止");
});
controller.abort();
4.3 重用與限制
一個(gè) AbortController 只能中止一次,之后就不能再使用了:
const controller = new AbortController(); controller.abort(); controller.abort(); // 第二次調(diào)用不會(huì)有任何效果
如果需要多次中止操作,需要?jiǎng)?chuàng)建新的 AbortController 實(shí)例。
4.4 與其他 API 集成
除了 fetch,AbortController 還可以用于其他 API:
// Web APIs
const videoStream = await navigator.mediaDevices.getUserMedia({
video: true,
signal: controller.signal
});
// Axios
const source = axios.CancelToken.source();
axios.get("/api/data", {
cancelToken: source.token
});
source.cancel();
4.5 自定義中止邏輯
你可以基于 AbortSignal 實(shí)現(xiàn)自己的可中止操作:
function doTask(signal) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => resolve("任務(wù)完成"), 5000);
signal.addEventListener("abort", () => {
clearTimeout(timer);
reject(new DOMException("任務(wù)被中止", "AbortError"));
});
if (signal.aborted) {
clearTimeout(timer);
reject(new DOMException("任務(wù)被中止", "AbortError"));
}
});
}
const controller = new AbortController();
doTask(controller.signal)
.then(console.log)
.catch((err) => {
if (err.name === "AbortError") {
console.log("任務(wù)被中止");
}
});
// 中止任務(wù)
controller.abort();
到此這篇關(guān)于js中AbortController請(qǐng)求中止的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)js AbortController請(qǐng)求中止內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript定時(shí)器取消定時(shí)器及優(yōu)化方法
這篇文章主要介紹了 javascript定時(shí)器取消定時(shí)器及js定時(shí)器優(yōu)化方法的相關(guān)資料,需要的朋友可以參考下2017-07-07
JavaScript文件上傳功能詳解與實(shí)現(xiàn)過程
現(xiàn)代Web開發(fā)中,文件上傳一般通過JavaScript來處理,以便實(shí)現(xiàn)更好的用戶體驗(yàn),如異步上傳(AJAX)、進(jìn)度條顯示等,這篇文章主要介紹了JavaScript文件上傳功能詳解與實(shí)現(xiàn)過程的相關(guān)資料,需要的朋友可以參考下2025-04-04
微信小程序webview中監(jiān)聽返回按鈕實(shí)現(xiàn)步驟
在微信小程序中webview返回鍵是一個(gè)非常實(shí)用的功能,它允許用戶在嵌入的網(wǎng)頁中返回到上一個(gè)頁面,這篇文章主要給大家介紹了微信小程序webview中監(jiān)聽返回按鈕的實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-08-08
微信小程序?qū)崿F(xiàn)簡(jiǎn)易計(jì)算器
這篇文章介紹了微信小程序?qū)崿F(xiàn)簡(jiǎn)易計(jì)算器的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
詳解JS中的compose函數(shù)和pipe函數(shù)用法
這篇文章主要介紹了JS中的compose函數(shù)和pipe函數(shù)用法,想深入了解Javascript的同學(xué),可以參考下2021-04-04
關(guān)于js中removeEventListener取消事件監(jiān)聽的坑
許多入前端不久的人都會(huì)遇到removeEventListener無法清除監(jiān)聽的情況,下面這篇文章主要給大家介紹了關(guān)于js中removeEventListener取消事件監(jiān)聽的坑,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09

