Vue + fetchEventSource 使用 AbortController 遇到的“只能中止一次”問題解析與解決方案

前言

在前端項目中,使用 SSE(Server-Sent Events) 長連接去獲取實時消息已經很常見了。像 fetchEventSource 這種封裝好的工具,可以幫助我們輕松處理流式請求。

不過在實踐中,我遇到了一個奇怪的問題:點擊按鈕觸發 SSE 請求時,controller.abort() 只能生效一次,第二次再觸發就完全沒用了。本文記錄一下排查和解決過程。


問題復現

假設有如下代碼:

const controller = new AbortController();const onSubmit = () => {// 中止上一輪消息請求controller.abort();ElMessage.success("中止");// 建立新的消息請求fetchEventSource(url, {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({"name": "小明"}),openWhenHidden: true, // 窗口不可見時保持連接signal: controller.signal,	// 請求控制器:用于中止sse請求的onmessage(ev) {console.log("收到消息", ev.data);},});
};

第一次點擊按鈕時,能成功中止請求;
但第二次點擊時,請求卻再也中止不了了。


問題原因

問題的關鍵在于 AbortController 的 signal 只能使用一次

  • controller.abort() 調用后,controller.signal 就已經被標記為 aborted
  • 下一次再傳入同一個 signalfetchEventSource,它會發現這個 signal 已經失效,自然就無法再中止。

也就是說:AbortController 不能復用,每次請求都必須創建新的實例


解決方案

在 Vue 組件中,可以把 controllerref 管理,每次請求時都先 abort 上一個,再創建一個新的

正確寫法

import { ref } from "vue";const controller = ref(new AbortController());const onSubmit = () => {// 先中止上一次請求(如果存在)if (controller.value) {controller.value.abort();}// 創建新的 controllercontroller.value = new AbortController();fetchEventSource(url, {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify(body),signal: controller.value.signal,	// 用 ref 給onmessage(ev) {console.log("收到消息", ev.data);},onerror(err) {console.error("錯誤:", err);}});
};

總結

  • AbortController 是一次性消耗品,不能復用
  • 每次請求前必須 controller = new AbortController()
  • 在 Vue 中用 ref 管理 controller 更加清晰,方便中止和重置。

這樣寫就能保證:不管點多少次發送按鈕,每一次請求都能正確中止。

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

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

相關文章

Django get_or_create 方法詳解

get_or_create 是 Django ORM 中的一個非常常用的方法,它用于獲取數據庫中的一個對象,如果該對象不存在,則創建一個新的對象并返回。 方法簽名: Model.objects.get_or_create(defaultsNone, **kwargs)參數解釋: defaul…

LangChain 文檔問答系統中高級文本分割技術

告別語義斷裂:LangChain 文檔問答系統中高級文本分割技術深度指南 文章目錄 引言:問題的根源——為何精準的文本分割是 RAG 系統的命脈? 第一部分:探本溯源——剖析 LangChain 默認分割器的“機械之困” 機制解析:語法驅動的“暴力”切分 問題場景化展示:語義、上下文與結…

Web2 vs Web3--差異一看就懂

互聯網技術的浪潮不斷推動著我們從Web2時代向Web3時代邁進。這兩個時代在技術架構、用戶體驗、數據所有權等方面有著顯著的差異。本文將為您詳細解析Web2與Web3之間的差異,并探討它們如何塑造我們的數字生活。 定義 Web2,即第二代互聯網,以其…

深入解析MongoDB內部架構設計

MongoDB內部構造詳解 MongoDB作為一款流行的NoSQL數據庫,其內部構造設計獨特且高效。以下從多個維度詳細解析MongoDB的內部架構和核心組件。 一、整體架構 MongoDB采用分布式架構設計,主要包含以下核心組件:應用層:應用程序通過語…

ubuntu12.04安裝opencalib手動標定并使用自己的數據

ubuntu22.04安裝opencalib手動標定并使用自己的數據 一、OpenCalib的部署使用 1、基本信息 官網鏈接: https://github.com/PJLab-ADG/SensorsCalibration/tree/v0.2 (官網下載的zip文件是有問題的,不建議到官網下載) 參考鏈接: https://blog.csdn.net/qq_49959714/arti…

scss 轉為原子css unocss

文章目錄前言🎯 **方案一:混合模式 (推薦)**🎯 **方案二:語義化組件類**🎯 **方案三:CSS 模塊化**🎯 **方案四:BEM 命名規范**💡 **推薦做法**前言 記錄讓c4 從scss 轉為…

【面試題】生成式排序了解嗎?

生成式排序是搜索排序的前沿方向,核心思想是利用生成式模型的能力來改善排序效果。 技術實現方式:序列到序列重排序 將候選文檔列表作為輸入序列使用encoder-decoder模型生成重排后的文檔序列優勢:能捕捉文檔間的全局相關性生成式特征提取 使…

【系統架構設計(15)】軟件架構設計一:軟件架構概念與基于架構的軟件開發

文章目錄一、核心思想二、軟件架構概念:系統設計的高級抽象三、軟件架構設計與生命周期:架構在開發流程中的演進四、架構描述語言ADL:架構的標準化表達五、41視圖:多角度的架構展現六、基于架構的軟件開發概念:架構驅動…

文件系統-哈希結構文件

一、核心思想哈希文件的核心思想非常簡單直接:通過一個計算(哈希函數),將記錄的鍵(Key)直接轉換為該記錄在磁盤上的物理地址(通常是塊地址),從而實現對記錄的快速存取。它…

一文吃透 C#中異步編程Task

一文吃透 C#中異步編程Task 一、Task 是什么 二、推薦使用場景 三、Demo:Task 的核心用法 1. 最常用的啟動方式Task.Run 2. task完成狀態與結果獲取 3. 多個任務怎么等?Wait/WaitAll/WaitAny 4. 任務想中途停掉?取消與異常處理 四、必備 API 速查表 五、避坑指南、注意事項 …

TDengine TIMETRUNCATE 函數用戶使用手冊

TDengine TIMETRUNCATE 函數用戶使用手冊 函數概述 TIMETRUNCATE 是 TDengine 中的一個時間處理標量函數,用于將時間戳按照指定的時間單位進行截斷操作。該函數在時間數據聚合、分組和統計分析中非常有用,特別適用于智能電表等時序數據的分析場景。 語法…

KSZ8081寄存器介紹

一、寄存器概覽KSZ8081MNX/RNB 支持 IEEE 802.3 標準的 MII 管理接口(MDIO),寄存器地址范圍為 0x00 - 0x1F,其中寄存器 0x00 - 0x08 為 IEEE 標準寄存器,0x09 - 0x1F 為擴展功能寄存器。寄存器按功能可分為基本控制與狀…

力扣190:顛倒二進制位

力扣190:顛倒二進制位題目思路代碼題目 顛倒給定的 32 位無符號整數number的二進制位。 思路 思路很簡單,我們只需要得到number從低位到高位的每一個二進制位再把二進制位移到顛倒的res的對應二進制位即可,例如number的最低位為1那么res的最高位即1&a…

鴻蒙NEXT交互機制解析:從輸入設備到手勢響應的全面指南

深入探索鴻蒙NEXT的交互設計,掌握下一代人機交互核心技術在智能設備無處不在的今天,一個操作系統的交互設計質量直接影響著用戶體驗。鴻蒙NEXT作為華為推出的新一代操作系統,在交互設計上帶來了許多創新和突破。本文將全面解析鴻蒙NEXT的交互…

通過IDEA寫一個服務端和一個客戶端之間的交互

服務端代碼:WebSocketConfig代碼package org.example.hufamessagedemo;import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.*;Configuration EnableWebSocket public class WebSocketConfig i…

玩客云刷機Armbian + CasaOS,輕nas系統,以及擴展

網上太多的教程,綜合了一下,自己一邊參考一邊嘗試,昨天晚上做的,感覺今天快忘了,記錄一下,少走彎路。 隨著礦潮的退去,市場上涌現出了眾多所謂的“礦渣盒子”,這些設備往往因為價格低…

【Linux】環境變量與程序地址空間詳解

前言:歡迎各位光臨本博客,這里小編帶你直接手撕Linux程序地址空間,文章并不復雜,愿諸君耐其心性,忘卻雜塵,道有所長!!!! **🔥個人主頁&#xff1a…

機器學習 - Kaggle項目實踐(8)Spooky Author Identification 作者識別

Spooky Author Identification | Kaggle Approaching (Almost) Any NLP Problem on Kaggle (參考) Spooky Author Identification | Kaggle (My work) 根據三位的一些作品訓練集,三分類測試集是哪個作家寫的概率。 …

[frontend]WebGL是啥?

對于初學者來說,通常的建議是: 不要直接從原生 WebGL 開始,而是先使用一個基于 WebGL 的高級框架或庫,最著名的就是 Three.js。 webgl是啥 three.js是啥? Three.js 封裝了 WebGL 的復雜細節,提供了更簡單、…

[光學原理與應用-400]:設計 - 深紫外皮秒脈沖激光器 - 元件 - 聲光調制器AOM

聲光調制器(Acousto-Optic Modulator, AOM)是深紫外皮秒脈沖激光器中實現脈沖主動控制、頻率穩定及光束管理的核心元件。其通過聲波與光波的彈光相互作用,在皮秒時間尺度內實現激光強度、頻率或傳播方向的精準調制。以下從工作原理、關鍵性能…