XHR / Fetch / Axios 請求的取消請求與請求重試

XHR / Fetch / Axios 請求的取消請求請求重試是前端性能優化與穩定性處理的重點,也是面試高頻內容。下面是這三種方式的詳解封裝方案(可直接復用)。


? 一、Axios 取消請求與請求重試封裝

1. 安裝依賴(可選,用于擴展)

npm install axios

2. 封裝 cancelToken 與 retry 的 axios 請求模塊

// axiosRequest.js
import axios from 'axios'const pendingMap = new Map()// 生成唯一 key(用于標記請求)
function getRequestKey(config) {const { method, url, params, data } = configreturn [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}// 添加請求到 pendingMap
function addPending(config) {const key = getRequestKey(config)config.cancelToken = new axios.CancelToken(cancel => {if (!pendingMap.has(key)) {pendingMap.set(key, cancel)}})
}// 移除請求
function removePending(config) {const key = getRequestKey(config)if (pendingMap.has(key)) {const cancel = pendingMap.get(key)cancel && cancel()pendingMap.delete(key)}
}// 重試機制封裝
function retryAdapterEnhancer(adapter, options = {}) {const { retries = 3, delay = 1000 } = optionsreturn async config => {let retryCount = 0const request = async () => {try {return await adapter(config)} catch (err) {if (retryCount < retries) {retryCount++await new Promise(res => setTimeout(res, delay))return request()} else {return Promise.reject(err)}}}return request()}
}// 創建實例
const axiosInstance = axios.create({timeout: 5000,adapter: retryAdapterEnhancer(axios.defaults.adapter, { retries: 2, delay: 1000 })
})// 請求攔截器
axiosInstance.interceptors.request.use(config => {removePending(config)addPending(config)return config
})// 響應攔截器
axiosInstance.interceptors.response.use(response => {removePending(response.config)return response},error => {if (axios.isCancel(error)) {console.warn('Request canceled:', error.message)}return Promise.reject(error)}
)export default axiosInstance

? 使用示例:

import request from './axiosRequest'request.get('/api/data', { params: { id: 1 } }).then(res => console.log(res)).catch(err => console.error(err))

? 二、Fetch 封裝(支持取消請求 & 重試)

1. 使用 AbortController 封裝取消與重試

// fetchRequest.js
export function fetchWithRetry(url, options = {}, retries = 3, delay = 1000) {const controller = new AbortController()options.signal = controller.signalconst fetchData = (retryCount = 0) => {return fetch(url, options).then(res => {if (!res.ok) throw new Error('Network response was not ok')return res}).catch(err => {if (retryCount < retries && err.name !== 'AbortError') {return new Promise(resolve =>setTimeout(() => resolve(fetchData(retryCount + 1)), delay))}throw err})}return {promise: fetchData(),cancel: () => controller.abort()}
}

? 使用示例:

const { promise, cancel } = fetchWithRetry('/api/data', {}, 2, 1000)promise.then(res => res.json()).then(data => console.log(data)).catch(err => console.error(err))// 調用 cancel() 可隨時取消請求

? 三、XHR 原生封裝(帶取消 & 重試)

// xhrRequest.js
export function xhrWithRetry({ url, method = 'GET', data = null, retries = 3, delay = 1000 }) {let xhr = nullconst send = (retryCount = 0, resolve, reject) => {xhr = new XMLHttpRequest()xhr.open(method, url, true)xhr.onreadystatechange = () => {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.responseText)} else if (retryCount < retries) {setTimeout(() => send(retryCount + 1, resolve, reject), delay)} else {reject(new Error(`Request failed: ${xhr.status}`))}}}xhr.onerror = () => reject(new Error('Network Error'))xhr.send(data)}const promise = new Promise((resolve, reject) => send(0, resolve, reject))return {promise,cancel: () => xhr && xhr.abort()}
}

? 使用示例:

const { promise, cancel } = xhrWithRetry({ url: '/api/data' })promise.then(res => console.log(res)).catch(err => console.error(err))// 可隨時調用取消
cancel()

? 總結對比

特性/方式取消支持重試支持易用性推薦場景
Axios?? CancelToken?? 自定義 adapter? 最佳Vue/React 項目
Fetch?? AbortController?? 手動封裝? 清晰原生 / SSR 項目
XHR?? abort()?? 手動封裝? 復雜老舊兼容需求

如果你想把這三套方案整合成一個通用庫或 TypeScript 模塊,我也可以幫你封裝成統一接口版本。是否需要我繼續處理這部分?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83928.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83928.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83928.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025最新Java日志框架深度解析:Log4j 2 vs Logback性能實測+企業級實戰案例

一、為什么printStackTrace是"代碼墳場"&#xff1f; 你寫的日志可能正在拖垮系統&#xff01; 在Java開發中&#xff0c;直接調用printStackTrace()打印異常堆棧是最常見的"自殺式操作"。這種方式會導致三大致命問題&#xff1a; 無法分級控制&#xff…

前端面試四之Fetch API同步和異步

Fetch API&#xff08;Fetch Application Programming Interface&#xff09;是一個現代的、基于Promise的網絡請求接口&#xff0c;用于在瀏覽器環境中發起網絡請求并處理響應。它是對傳統XMLHttpRequest的改進&#xff0c;提供了更簡潔、靈活和強大的功能&#xff0c;廣泛應用…

ubuntu 20.04掛載固態硬盤

我們有個工控機&#xff0c;其操作系統是ubuntu 20.04。可以接入一個固態硬盤。將固態硬盤插好后&#xff0c;就要進行掛載。在AI的指導下&#xff0c;過程并不順利。記錄如下&#xff1a; 1、檢查硬盤是否被識別 安裝好硬盤后&#xff0c;運行以下命令來檢查Linux系統是否…

涂裝協作機器人:重新定義涂裝工藝的智能化未來

一、涂裝場景的產業變革與核心訴求 1.1 千億級市場的技術突圍戰 在汽車制造領域&#xff0c;涂裝車間被稱為"工業化妝間"&#xff0c;其工藝質量直接影響產品溢價能力。當前行業面臨三重挑戰&#xff1a; 質量維度&#xff1a;傳統人工噴涂存在膜厚波動15μm的行業…

Unity優化篇之DrawCall

當然可以&#xff01;以下是完整、詳盡、可發布的博客文章&#xff0c;專注講解 Unity 的靜態合批與動態合批機制&#xff0c;并詳細列出它們對 Shader 的要求和所有限制條件。文章結構清晰、技術深度足夠&#xff0c;適合發布在 CSDN、掘金、知乎等技術平臺。 urp默認隱藏動態…

Electron桌面應用下,在拍照、展示pdf等模塊時,容易導致應用白屏

Electron 應用白屏問題分析與解決方案 Electron 應用中拍照、PDF展示等模塊導致白屏的常見原因通常與內存泄漏、渲染進程崩潰或資源加載超時有關。以下是具體排查與解決方法&#xff1a; 檢查內存泄漏 項目中&#xff0c;分析代碼&#xff0c;高頻操作或未釋放的資源可能導致…

比對++Hex or Bin文件

用NotePad 安裝 ?? Hex-Editor 插件 1.1參考方法路徑https://cloud.tencent.com/developer/article/2311013 1.2 下載 Hex-Editor.dll文件路勁 https://sourceforge.net/projects/npp-plugins/ 比對 2.1, 顯示Bin 插件/Hex Editor/View in Hex 2.2 插件/Compare(運行很不流…

以STM32H7微控制器為例,簡要說明stm32h7xx_it.c的作用

在STM32開發中&#xff0c;stm32h7xx_it.c文件是中斷服務例程&#xff08;ISR, Interrupt Service Routine&#xff09;的核心實現文件&#xff0c;其作用與產生的邏輯如下&#xff1a; 一、文件的核心作用 中斷處理入口 該文件定義了STM32H7微控制器所有硬件中斷和異常的處理函…

若依框架頁面緩存查詢條件后,切換頁面想重新請求一下數據

因為框架使用了Keep-Alive緩存組件&#xff0c;所以使用onActivated鉤子 import { onActivated } from vue;// 當組件從緩存中重新激活時 onActivated(() > {getList(); });

智能心理醫療助手開發實踐:從技術架構到人文關懷——CangjieMagic情感醫療應用技術實踐

作為一名長期耕耘在醫療健康領域的技術開發者&#xff0c;我至今仍清晰地記得三年前那個深夜——當我調試的心理健康AI第一次對用戶的情緒崩潰做出恰當回應時&#xff0c;整個團隊爆發的歡呼聲。那一刻&#xff0c;我深刻意識到技術不只是冰冷的邏輯&#xff0c;更可以成為溫暖…

漢諾塔問題深度解析

漢諾塔問題深度解析 一、漢諾塔問題的起源與背景1.1 問題起源1.2 歷史發展 二、漢諾塔問題的描述與規則2.1 問題描述2.2 示例說明 三、漢諾塔問題的遞歸求解原理3.1 遞歸思想概述3.2 漢諾塔問題的遞歸分解3.3 遞歸調用棧分析 四、漢諾塔問題的多語言實現4.1 Python實現4.2 C實現…

【Node.js 深度解析】npm install 遭遇:npm ERR! code CERT_HAS_EXPIRED 錯誤的終極解決方案

目錄 &#x1f4da; 目錄&#xff1a;洞悉癥結&#xff0c;精準施治 &#x1f50d; 一、精準剖析&#xff1a;CERT_HAS_EXPIRED 的本質 &#x1f575;? 二、深度溯源&#xff1a;證書失效的 N 重誘因 &#x1f4a1; 三、高效解決策略&#xff1a;六脈神劍&#xff0c;招招…

【SpringBoot自動化部署】

SpringBoot自動化部署方法 使用Jenkins進行持續集成與部署 Jenkins是最常用的自動化部署工具之一&#xff0c;能夠實現代碼拉取、構建、測試和部署的全流程自動化。 配置Jenkins任務時&#xff0c;需要添加Git倉庫地址和憑證&#xff0c;設置構建觸發器&#xff08;如GitHub…

動態規劃-1035.不相交的線-力扣(LeetCode)

一、題目解析 光看題目要求和例圖&#xff0c;感覺這題好麻煩&#xff0c;直線不能相交啊&#xff0c;每個數字只屬于一條連線啊等等&#xff0c;但我們結合題目所給的信息和例圖的內容&#xff0c;這不就是最長公共子序列嗎&#xff1f;&#xff0c;我們把最長公共子序列連線起…

Double/Debiased Machine Learning

獨立同步分布的觀測數據 { W i ( Y i , D i , X i ) ∣ i ∈ { 1 , . . . , n } } \{W_i(Y_i,D_i,X_i)| i\in \{1,...,n\}\} {Wi?(Yi?,Di?,Xi?)∣i∈{1,...,n}}&#xff0c;其中 Y i Y_i Yi?表示結果變量&#xff0c; D i D_i Di?表示因變量&#xff0c; X i X_i Xi?表…

Tailwind CSS 實戰:基于 Kooboo 構建 AI 對話框頁面(八):異步處理邏輯詳解

在現代 Web 應用中&#xff0c;異步處理是實現流暢交互的核心技術。本文基于前幾章實現的內容Tailwind CSS 實戰&#xff1a;基于 Kooboo 構建 AI 對話框頁面&#xff08;七&#xff09;&#xff1a;消息框交互功能添加-CSDN博客&#xff0c;深入解析 AI 對話框頁面中異步邏輯的…

Asp.net Core 通過依賴注入的方式獲取用戶

思路&#xff1a;Web項目中&#xff0c;需要根據當前登陸的用戶&#xff0c;查詢當前用戶所屬的數據、添加并標識對象等。根據請求頭Authorization 中token&#xff0c;獲取Redis中存儲的用戶對象。 本做法需要完成 基于StackExchange.Redis 配置&#xff0c;參考&#xff1a;…

Vue3 + UniApp 藍牙連接與數據發送(穩定版)

本教程適用于使用 uni-app Vue3 (script setup) 開發的跨平臺 App&#xff08;支持微信小程序、H5、Android/iOS 等&#xff09; &#x1f3af; 功能目標 ? 獲取藍牙權限? 掃描周圍藍牙設備? 連接指定藍牙設備? 獲取服務和特征值? 向設備發送數據包&#xff08;ArrayBu…

Docker + Nginx + Logrotate 日志管理與輪換實踐

概述與背景 Docker 容器化環境中 Nginx 日志管理的挑戰Logrotate 的作用與必要性結合場景的實際需求&#xff08;如日志切割、壓縮、歸檔&#xff09; Docker 環境下的 Nginx 日志配置 Nginx 日志路徑與 Docker 數據卷映射 volumes:- ./nginx/logs:/var/log/nginxLogrotate …

涂膠協作機器人解決方案 | Kinova Link 6 Cobot在涂膠工業的方案應用與價值

涂膠工業現狀背景&#xff1a; 涂膠工藝在汽車制造、電子組裝、航空航天等工業領域極為關鍵&#xff0c;關乎產品密封、防水、絕緣性能及外觀質量。 然而&#xff0c;傳統涂膠作業問題頻發。人工操作重復性強易疲勞&#xff0c;涂膠質量波動大&#xff1b;大型涂膠器使用增加工…