最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文深入詳解Axios請(qǐng)求取消機(jī)制

 更新時(shí)間:2025年11月28日 08:34:15   作者:拉不動(dòng)的豬  
Axios 是一個(gè)基于 Promise 的 HTTP 客戶端,用于瀏覽器和 Node.js,在實(shí)際開(kāi)發(fā)中,有時(shí)候需要取消已經(jīng)發(fā)起的請(qǐng)求,下面小編就和大家簡(jiǎn)單聊聊Axios的請(qǐng)求取消機(jī)制吧

Axios是否真的支持取消請(qǐng)求呢

是的,Axios 完全支持取消請(qǐng)求。

Axios 提供了兩種主要的取消請(qǐng)求的方式:

  • 使用 AbortController (推薦,現(xiàn)代瀏覽器和 Node.js 環(huán)境)
  • 使用 CancelToken (舊版方式,Axios 0.22.0 之前的主要方式,現(xiàn)在已廢棄但仍兼容)

1. 使用AbortController(推薦)

AbortController 是 Web 標(biāo)準(zhǔn) API,用于中止一個(gè)或多個(gè) Web 請(qǐng)求。Axios 從 v0.22.0 開(kāi)始支持它,并推薦使用這種方式。

示例代碼:

import axios from 'axios';

// 1. 創(chuàng)建一個(gè) AbortController 實(shí)例
const controller = new AbortController();
const signal = controller.signal; // 獲取 AbortSignal 對(duì)象

// 2. 在 Axios 請(qǐng)求配置中傳入 signal
axios.get('/api/data', { signal })
  .then(response => {
    console.log('請(qǐng)求成功:', response.data);
  })
  .catch(error => {
    // 檢查錯(cuò)誤是否是由于請(qǐng)求取消引起的
    if (axios.isCancel(error)) {
      console.log('請(qǐng)求被取消:', error.message);
    } else {
      console.log('請(qǐng)求發(fā)生錯(cuò)誤:', error.message);
    }
  });

// 3. 在需要取消請(qǐng)求時(shí)調(diào)用 controller.abort()
// 例如,在組件卸載時(shí),或者用戶點(diǎn)擊了取消按鈕時(shí)
setTimeout(() => {
  controller.abort(); // 這會(huì)觸發(fā) signal 上的 abort 事件,Axios 會(huì)捕獲并取消請(qǐng)求
  console.log('請(qǐng)求已嘗試取消');
}, 100); // 100ms 后取消請(qǐng)求

優(yōu)點(diǎn):

  • 是 Web 標(biāo)準(zhǔn) API,不僅限于 Axios,也可以用于 fetch API 或其他支持 AbortSignal 的異步操作。
  • 更現(xiàn)代、更簡(jiǎn)潔的 API 設(shè)計(jì)。
  • 可以取消多個(gè)請(qǐng)求(將同一個(gè) signal 傳遞給多個(gè)請(qǐng)求)。

2. 使用CancelToken(舊版,已廢棄但仍兼容)

CancelToken 是 Axios 早期提供的取消請(qǐng)求機(jī)制。雖然現(xiàn)在推薦使用 AbortController,但如果你在使用舊版本的 Axios 或者需要兼容舊代碼,它仍然可用。

示例代碼:

import axios from 'axios';

// 1. 創(chuàng)建一個(gè) CancelToken.Source 工廠函數(shù)
const CancelToken = axios.CancelToken;
const source = CancelToken.source(); // source 對(duì)象包含 token 和 cancel 方法

// 2. 在 Axios 請(qǐng)求配置中傳入 token
axios.get('/api/data', { cancelToken: source.token })
  .then(response => {
    console.log('請(qǐng)求成功:', response.data);
  })
  .catch(error => {
    // 檢查錯(cuò)誤是否是由于請(qǐng)求取消引起的
    if (axios.isCancel(error)) {
      console.log('請(qǐng)求被取消:', error.message);
    } else {
      console.log('請(qǐng)求發(fā)生錯(cuò)誤:', error.message);
    }
  });

// 3. 在需要取消請(qǐng)求時(shí)調(diào)用 source.cancel()
// 例如,在組件卸載時(shí),或者用戶點(diǎn)擊了取消按鈕時(shí)
setTimeout(() => {
  source.cancel('用戶取消了請(qǐng)求'); // 傳入一個(gè)可選的消息
  console.log('請(qǐng)求已嘗試取消');
}, 100); // 100ms 后取消請(qǐng)求

優(yōu)點(diǎn):

在舊版本 Axios 中廣泛使用。

缺點(diǎn):

  • Axios 特有的 API,不適用于其他 Web API。
  • 已被 AbortController 替代,未來(lái)可能不再維護(hù)或推薦。

何時(shí)需要取消請(qǐng)求

取消請(qǐng)求在前端開(kāi)發(fā)中非常有用,常見(jiàn)場(chǎng)景包括:

  • 組件卸載時(shí):當(dāng)用戶在請(qǐng)求完成前切換頁(yè)面或組件被銷(xiāo)毀時(shí),避免因請(qǐng)求返回后嘗試更新已不存在的組件狀態(tài)而導(dǎo)致的內(nèi)存泄漏或錯(cuò)誤。
  • 用戶操作取消:例如,用戶點(diǎn)擊了“取消上傳”按鈕,或在搜索框中快速輸入時(shí),取消之前的舊搜索請(qǐng)求,只保留最新的請(qǐng)求。
  • 避免重復(fù)請(qǐng)求:在某些情況下,為了防止用戶多次點(diǎn)擊或快速觸發(fā)某個(gè)操作導(dǎo)致發(fā)送多個(gè)相同的請(qǐng)求,可以在新請(qǐng)求發(fā)出前取消舊請(qǐng)求。

總之,Axios 提供了強(qiáng)大且靈活的請(qǐng)求取消機(jī)制,推薦在現(xiàn)代項(xiàng)目中使用 AbortController。

這種取消是前端拒絕接收數(shù)據(jù)還是真的停止http的請(qǐng)求鏈接呢?

1. 它是如何“真取消”的?(瀏覽器層面)

當(dāng)你調(diào)用 controller.abort()(或舊版的 cancelToken)時(shí),Axios 會(huì)調(diào)用瀏覽器底層的 API(XMLHttpRequest.abort() 或 fetch 的 signal 機(jī)制)。

這意味著:

  • 網(wǎng)絡(luò)連接被切斷:瀏覽器會(huì)立即關(guān)閉與服務(wù)器的 TCP 連接。
  • 停止接收數(shù)據(jù):如果服務(wù)器正在發(fā)送一個(gè)很大的響應(yīng)(比如下載一個(gè) 100MB 的文件),瀏覽器會(huì)立刻停止下載,節(jié)省帶寬
  • Promise 立即 Reject:Axios 的 Promise 會(huì)立刻拋出一個(gè) CanceledError,你的代碼會(huì)立刻進(jìn)入 .catch(),而不需要等待服務(wù)器響應(yīng)超時(shí)。

對(duì)比:  如果僅僅是“前端不予接收”,瀏覽器會(huì)傻傻地把 100MB 下載完,然后你的代碼再把數(shù)據(jù)扔掉。Axios 的取消是前者,直接掐斷連接,節(jié)省資源。

2. 服務(wù)器端發(fā)生了什么?(后端層面)

這是最容易產(chǎn)生誤解的地方。 “前端取消了請(qǐng)求”并不代表“后端撤銷(xiāo)了操作”。

請(qǐng)求已發(fā)出:在大多數(shù)情況下,當(dāng)你點(diǎn)擊取消時(shí),請(qǐng)求指令已經(jīng)通過(guò)網(wǎng)絡(luò)發(fā)送到了服務(wù)器。

服務(wù)器正在處理:服務(wù)器收到請(qǐng)求后,開(kāi)始查詢數(shù)據(jù)庫(kù)、計(jì)算數(shù)據(jù)或?qū)懭胗涗洝?/p>

連接中斷:此時(shí)前端斷開(kāi)了連接。

  • 大多數(shù)后端框架(如 Java Spring, Node Express, Python Flask) :通常不會(huì)自動(dòng)檢測(cè)連接斷開(kāi)而停止業(yè)務(wù)邏輯。它們會(huì)繼續(xù)把活干完(比如把數(shù)據(jù)寫(xiě)進(jìn)數(shù)據(jù)庫(kù)),然后試圖把結(jié)果返回給前端。
  • 結(jié)果:當(dāng)服務(wù)器試圖返回結(jié)果時(shí),發(fā)現(xiàn)連接已經(jīng)沒(méi)了,服務(wù)器會(huì)報(bào)錯(cuò)(如 Broken pipe),但之前的業(yè)務(wù)邏輯(如寫(xiě)庫(kù))可能已經(jīng)執(zhí)行了。

舉個(gè)例子:

你在餐廳點(diǎn)了一道菜(發(fā)送請(qǐng)求)。

廚師開(kāi)始做菜(服務(wù)器處理)。

你突然有急事走了,跟服務(wù)員說(shuō)“我不要了”(前端取消請(qǐng)求)。

  • 前端視角:你走了,沒(méi)吃到菜,也沒(méi)付錢(qián)(節(jié)省了時(shí)間和資源)。
  • 后端視角:廚師可能已經(jīng)把菜做好了,發(fā)現(xiàn)沒(méi)人吃,只能倒掉。但菜確實(shí)被做出來(lái)了(副作用已產(chǎn)生)。

3. 總結(jié):三種情況

根據(jù)取消的時(shí)機(jī)不同,效果也不同:

請(qǐng)求還在排隊(duì)(極少見(jiàn))

  • 瀏覽器還沒(méi)來(lái)得及把請(qǐng)求發(fā)出去你就取消了。
  • 結(jié)果:服務(wù)器完全不知道有這回事,這是最徹底的取消。

請(qǐng)求在傳輸中/服務(wù)器處理中(最常見(jiàn))

  • 請(qǐng)求已發(fā),服務(wù)器正在算,前端取消。
  • 結(jié)果:前端斷開(kāi)連接,不再等待。服務(wù)器可能還是會(huì)把活干完,但發(fā)不回來(lái)。這對(duì)前端來(lái)說(shuō)是真取消(不卡界面、不費(fèi)流量),對(duì)后端來(lái)說(shuō)通常無(wú)法撤銷(xiāo)副作用。

響應(yīng)已到達(dá)瀏覽器

  • 服務(wù)器數(shù)據(jù)已經(jīng)發(fā)回來(lái)了,瀏覽器剛收到,你正好點(diǎn)了取消。
  • 結(jié)果:這時(shí)候其實(shí)已經(jīng)晚了,Axios 只是拋個(gè)錯(cuò)讓你忽略結(jié)果。這就變成了你說(shuō)的“前端不予接收”。

核心建議

用于優(yōu)化體驗(yàn):Axios 的取消非常適合用于搜索框聯(lián)想(輸入 a 發(fā)請(qǐng)求,緊接著輸入 ab,此時(shí)取消 a 的請(qǐng)求)或切換 Tab。這能有效防止“舊數(shù)據(jù)的響應(yīng)覆蓋了新數(shù)據(jù)”的 Bug,并節(jié)省帶寬。

不要依賴(lài)它來(lái)回滾數(shù)據(jù):如果你發(fā)的是 POST 請(qǐng)求(比如“付款”),千萬(wàn)不要指望前端取消就能阻止服務(wù)器扣款。后端必須要有冪等性設(shè)計(jì)或?qū)iT(mén)的撤銷(xiāo)接口。

到此這篇關(guān)于一文深入詳解Axios請(qǐng)求取消機(jī)制的文章就介紹到這了,更多相關(guān)Axios請(qǐng)求取消機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

长沙县| 合水县| 维西| 凉山| 吕梁市| 东辽县| 疏勒县| 凉城县| 钟山县| 大渡口区| 沂水县| 苍梧县| 彝良县| 黄梅县| 石城县| 北碚区| 昌吉市| 兴化市| 汉川市| 淅川县| 香格里拉县| 双柏县| 县级市| 安宁市| 延边| 临颍县| 镇宁| 固镇县| 平舆县| 华宁县| 米林县| 华亭县| 土默特左旗| 申扎县| 平利县| 西贡区| 郓城县| 金阳县| 易门县| 云阳县| 揭阳市|