vue3+ts网页开发 web serial api读取串口数据 Failed to execute 'getReader' on 'ReadableStream': ReadableStreamDefaultReader constructor can only accept readable streams that are not yet locked to a reader at SerialService.connect

时间: 2025-08-03 09:23:19 浏览: 2
<think>我们面对的问题是在Vue3和TypeScript环境下使用WebSerialAPI时出现的错误:"Failedtoexecute'getReader'on'ReadableStream':ReadableStreamDefaultReaderconstructorcanonlyacceptreadablestreamsthatarenotyetlockedtoareader"错误原因:当我们对一个已经被锁定的ReadableStream再次调用getReader()时,就会抛出此错误。在串口通信中,我们可能会在多个地方尝试读取同一个流,或者在未释放读取器的情况下重复创建读取器。解决方案:###1.确保单次读取器绑定确保在任意时刻,每个ReadableStream只绑定一个读取器。在创建新的读取器之前,必须释放之前绑定的读取器。###2.使用`stream.locked`检查状态在尝试获取读取器之前,检查流是否已被锁定:```typescriptif(port.readable&&!port.readable.locked){constreader=port.readable.getReader();//使用读取器...}```###3.正确释放读取器当不再需要读取器时(如组件卸载或读取完成后),需要调用`reader.releaseLock()`释放锁,并确保读取器不再被使用。###4.封装读取操作将读取操作封装到一个独立的函数中,使用`try...finally`确保读取器被释放:```typescriptasyncfunctionreadSerialData(port:SerialPort){if(!port.readable||port.readable.locked)return;constreader=port.readable.getReader();try{while(true){const{value,done}=awaitreader.read();if(done)break;//处理数据,例如:console.log(newTextDecoder().decode(value));}}catch(error){console.error('读取错误:',error);}finally{reader.releaseLock();}}```###5.在Vue组件中使用在Vue3组件中,结合`onUnmounted`生命周期钩子,确保组件卸载时释放资源:```typescriptimport{onUnmounted,ref}from'vue';importtype{SerialPort}from'web-serial-polyfill';//或实际使用的类型exportdefault{setup(){constport=ref<SerialPort|null>(null);letreader:ReadableStreamDefaultReader|null=null;asyncfunctionconnect(){//请求串口constserialPort=awaitnavigator.serial.requestPort();awaitserialPort.open({baudRate:9600});port.value=serialPort;//开始读取if(serialPort.readable&&!serialPort.readable.locked){reader=serialPort.readable.getReader();readLoop();}}asyncfunctionreadLoop(){if(!reader)return;try{while(true){const{value,done}=awaitreader.read();if(done)break;//处理数据...}}catch(error){console.error('读取失败',error);}}functiondisconnect(){if(reader){reader.releaseLock();reader=null;}if(port.value){port.value.close();port.value=null;}}onUnmounted(()=>{disconnect();});return{connect,disconnect};}};```###6.避免重复读取确保在连接串口时只创建一次读取器,不要多次调用读取器创建函数。###错误场景复现及修复假设以下错误代码:```typescript//错误示例:在同一个流上多次创建读取器asyncfunctionreadTwice(port:SerialPort){constreader1=port.readable.getReader();//第一次锁定constreader2=port.readable.getReader();//这里会抛出错误}```修复后:```typescript//正确:使用释放锁后再创建新读取器asyncfunctionreadTwice(port:SerialPort){constreader1=port.readable.getReader();//读取一些数据...reader1.releaseLock();//先释放if(!port.readable.locked){constreader2=port.readable.getReader();//现在可以创建//使用reader2...reader2.releaseLock();}}```###总结|错误原因|解决方法||----------|----------||流已被其他读取器锁定|检查`stream.locked`状态,确保流未锁定再获取||读取器未释放导致持续锁定|在读取完成后调用`releaseLock()`释放||组件卸载时未清理|使用Vue生命周期钩子`onUnmounted`释放资源|通过以上方法,您可以解决WebSerialAPI中ReadableStream的锁定问题[^1]。§§相关问题§§1.WebSerialAPI在Vue3中如何封装成可复用的Composable?2.如何优化串口数据的读取性能?3.WebSerialAPI的兼容性如何?有哪些替代方案?4.在TypeScript中如何定义WebSerialAPI的类型?</think> ### 解决 Vue3 TypeScript 中 Web Serial API 的 ReadableStream 锁定错误 在 Vue3 和 TypeScript 中使用 Web Serial API 时遇到 `Failed to execute 'getReader' on 'ReadableStream'` 错误,通常是由于未正确处理串口流的锁定机制导致的。以下是完整解决方案: #### 错误原因分析 1. **流锁定机制**:`ReadableStream` 只能被一个读取器(reader)锁定,重复调用 `getReader()` 会触发此错误 2. **常见场景**: - 多次调用 `connect()` 方法未断开前次连接 - 异步操作中未正确释放读取器 - Vue 组件销毁时未清理资源 - 并发读写操作冲突 #### 解决方案(Vue3 + TypeScript 实现) 1. **正确管理串口连接状态** ```typescript import { ref, onUnmounted } from 'vue' // 串口服务封装 class SerialService { private port: SerialPort | null = null private reader: ReadableStreamDefaultReader | null = null private isConnected = ref(false) async connect() { if (this.isConnected.value) { console.warn('串口已连接') return } try { // 请求并打开串口 this.port = await navigator.serial.requestPort() await this.port.open({ baudRate: 9600 }) // 检查流状态(关键步骤) if (this.port.readable && !this.port.readable.locked) { this.reader = this.port.readable.getReader() this.isConnected.value = true this.startReading() } } catch (error) { console.error('连接失败', error) } } private async startReading() { if (!this.reader) return try { while (this.isConnected.value) { const { value, done } = await this.reader.read() if (done) break // 处理接收到的数据: console.log(value) } } catch (error) { console.error('读取错误', error) } finally { this.releaseResources() } } private releaseResources() { // 关键:释放读取器和关闭端口 this.reader?.releaseLock() this.reader = null this.port?.close() this.port = null this.isConnected.value = false } disconnect() { this.releaseResources() } } // Vue3 组件中使用 export default { setup() { const serialService = new SerialService() const connectionStatus = ref(false) // 组件卸载时自动断开连接 onUnmounted(() => { serialService.disconnect() }) return { connect: async () => { await serialService.connect() connectionStatus.value = true }, disconnect: () => { serialService.disconnect() connectionStatus.value = false } } } } ``` 2. **关键优化点** - **流状态检查**:调用 `getReader()` 前检查 `!port.readable.locked` ```typescript if (this.port.readable && !this.port.readable.locked) { this.reader = this.port.readable.getReader() } ``` - **资源释放**:使用 `finally` 确保异常时也释放资源 - **组件生命周期**:通过 `onUnmounted` 自动清理 - **状态管理**:使用 `ref` 跟踪连接状态避免重复连接 3. **错误处理增强** ```typescript async connect() { if (this.isConnected.value) { // 解决方案:返回当前连接状态或错误提示 throw new Error('串口已被锁定,请先断开连接') } // ... } ``` 4. **串口操作最佳实践** - 每次数据传输完成后调用 `reader.releaseLock()` - 避免在并发异步操作中共享同一个读取器 - 使用 `AbortController` 处理长时间操作超时 #### 常见问题排查表 | 现象 | 解决方案 | |------|----------| | 刷新页面后连接失败 | 添加 `onUnmounted` 生命周期清理 | | 重复点击连接按钮报错 | 添加连接状态检查 `isConnected` | | 数据传输中断 | 增加 `try/catch/finally` 错误处理 | | 设备更换后连接失败 | 添加完整的端口释放逻辑 `releaseResources()` | #### 预防流锁定的关键要点 1. **单例模式**:确保每个串口只有单一读取器实例 2. **生命周期管理**:组件销毁时自动断开连接 3. **状态跟踪**:实时维护串口锁定状态 4. **错误边界**:处理 Web Serial API 的特定错误码: ```typescript catch (error) { if (error instanceof DOMException) { switch (error.name) { case 'NotAllowedError': console.error('用户拒绝访问') case 'NotFoundError': console.error('设备未找到') // 其他错误处理 } } } ``` 通过以上实现,可有效解决 Web Serial API 在 Vue3 中的流锁定问题[^1]。特别注意在异步操作和组件生命周期中管理读取器状态,这是避免错误的关键。
阅读全文

大家在看

recommend-type

tanner pro 集成电路设计和布局实战指导 配套 CD

《tanner pro 集成电路设计和布局实战指导》配套CD , 包含多有例子:有Layout和 code,学习非常方便。
recommend-type

SmartSVN license

和谐SmartSVN试用版的license,下载后覆盖即可。(注意:覆盖前最好备份原license)
recommend-type

AAA2.5及汉化补丁

Advanced Aircraft Analysis V2.5.1.53 (3A) 在win7 64位上安装测试。有注册机和安装视频。支持winxp和win732位和64位系统。 Darcorp Advanced Aircraft Analysis V2.5.1.53 (AAA) 软件是一款面向于高级用户的飞机设计和仿真分析软件,目前广泛应用于数十个国家的各种机构,已然成为飞机设计、开发、稳定性分析以及飞行控制的工业标准软件。适用于 FAR23、FAR25、UAV无人驾驶飞机与 Military 规范,为全球飞机公司(如波音公司)、政府部门(如 FAA)与学校采用于飞机初步设计、分析、与 3-D 绘图的一套完整软件工具。 Advanced Aircraft Analysis (AAA) 是行业标准的飞机设计,稳定性和控制分析软件。 安装在超过45个国家,AAA所使用的主要航空工程大学,飞机制造商和世界各地的军事组织。 Advanced Aircraft Analysis(AAA)是行业标准的飞机设计 AAA提供了一个功能强大的框架,以支持飞机初步设计迭代和非独特的过程。 AAA计划允许学生和初步设计工程师从早期的大小通过开环和闭环动态稳定性和灵敏度分析的重量,而该机的配置工作在监管和成本的限制。
recommend-type

TDC-GP22资料.zip

TDC-GP22 STM32F103和MSP430源代码以及TDC中英文芯片手册,现场图片和测试总结
recommend-type

Frequency-comb-DPLL:数字锁相环软件,用于使用Red Pitaya锁定频率梳

数字锁相环,用于使用红色火龙果锁定频率梳 固件/软件允许使用此硬件来锁相频率梳。 更一般而言,它与硬件一起提供了一个数字控制盒,该数字控制盒可以支持双通道锁相环,包括输入rf信号的前端IQ检测。 因此,虽然此数字控制盒可用于锁相其他系统,但下面的讨论假定用户正在操作频率梳。 入门 从“发布部分”( )下载所需的文件: 可以访问Python GUI的完整源代码存储库; b。 红火龙果的SD卡映像(red_pitaya_dpll_2017-05-31.zip) 阅读并遵循“ RedPitaya DPLL.pdf的说明和操作手册”文件。 软件版本 所需的Python发行版是WinPython-64bit-3.7.2( )。 FPGA Vivado项目在Vivado 2015.4中进行了编译,但是仅使用该软件就不需要安装Vivado。 附加信息 可以从NIST数字控制箱的说明手册中获得更多信

最新推荐

recommend-type

vue+web端仿微信网页版聊天室功能

【Vue+Web端仿微信网页版聊天室功能详解】 在Web开发中,构建一个类似微信的聊天室功能是一项挑战,但也是提升技能的好机会。本文将深入探讨如何使用Vue.js框架来实现这样一个功能丰富的聊天室。我们将关注Vue的...
recommend-type

vue+ts下对axios的封装实现

在Vue.js和TypeScript的开发环境中,我们常常需要对第三方库如axios进行封装,以便更好地管理和定制网络请求。本文将详细介绍如何在Vue+TS项目中对axios进行封装,包括设置拦截器来处理请求和响应。 首先,确保你...
recommend-type

基于vue+echarts 数据可视化大屏展示的方法示例

在现代Web开发中,数据可视化是一项关键技能,能够帮助用户更好地理解复杂的数据。本文将详细介绍如何利用Vue.js框架结合ECharts库创建数据可视化大屏展示。ECharts是一款由百度开发的开源JavaScript图表库,提供了...
recommend-type

vue+echarts实现动态绘制图表及异步加载数据的方法

【Vue + Echarts 实现动态绘制图表及异步加载数据】 在 Vue 框架中,结合 Echarts 图表库可以方便地实现动态绘制图表,包括折线图、柱状图等。Echarts 是一个基于 JavaScript 的开源可视化库,提供了丰富的图表类型...
recommend-type

vue读取本地的excel文件并显示在网页上方法示例

在Vue项目中,读取本地Excel文件并在网页上显示是一个常见的需求。这个示例通过引入第三方库`xlsx`和使用`axios`实现了一个无需后端服务器的解决方案。以下是实现步骤和关键知识点: 1. **安装依赖**:首先,你需要...
recommend-type

19年国赛服务器答案深度解析:网络搭建与应用

网络搭建与应用是一门涉及计算机网络规划、配置、管理和维护的技术学科。在19年的国家竞赛中,参与者需要展示他们对网络架构、网络设备、协议、安全等方面的知识,以及他们在真实世界问题解决中的实际应用能力。在网络搭建与应用19国赛服务器答案中,涉及的知识点可能包括但不限于以下几个方面: 1. 网络基础知识 - 了解网络的基本概念,包括网络的定义、分类(如LAN、WAN等)、网络的功能和网络协议栈(如TCP/IP模型)。 - 理解网络设备的功能和作用,例如交换机、路由器、防火墙等。 - 掌握网络通信的基本原理,包括数据链路层、网络层、传输层和应用层的协议和功能。 2. 网络设计与规划 - 学习如何根据不同的需求设计网络拓扑结构,例如星形、环形、总线型等。 - 掌握IP地址规划和子网划分的方法,如CIDR、VLSM等技术。 - 了解如何进行网络流量分析和带宽规划,以确保网络性能和稳定性。 3. 网络设备配置与管理 - 掌握交换机和路由器的配置命令,例如VLAN划分、路由协议配置、端口安全等。 - 理解网络设备的管理和维护策略,包括日志管理、性能监控和故障诊断。 4. 网络安全 - 学习网络安全的基本原则,包括数据加密、访问控制、入侵检测系统(IDS)和入侵防御系统(IPS)。 - 掌握常见的网络攻击手段及其防御措施,例如DDoS攻击、ARP欺骗、病毒和恶意软件的防御。 5. 服务器搭建与应用 - 了解不同类型的服务器和它们的应用场景,如Web服务器、数据库服务器、邮件服务器等。 - 学习服务器的安装、配置和管理方法,包括操作系统的安装、服务软件的部署、用户管理等。 6. 实践操作 - 通过搭建真实或虚拟的网络环境来实践理论知识,包括使用网络模拟软件(如GNS3、Packet Tracer等)进行网络设备配置和故障排除。 - 学习如何准备和参加网络相关的竞赛,包括时间管理和应对突发问题的策略。 在给定的压缩包子文件的文件名称列表中,“19年国赛服务器的答案”表明该文件包含具体的竞赛解答步骤和方法。文件可能涉及的是如何根据具体的网络搭建与应用的题目,一步一步地提供解题策略、配置命令和执行步骤等。具体内容可能包括: - 对竞赛题目需求的分析和理解。 - 对应的网络设计解决方案和实现步骤。 - 关键的配置命令和参数设置。 - 对于各种网络功能和安全性的测试方法。 - 可能遇到的问题及其解决方案。 综上所述,对于网络搭建与应用19国赛服务器答案的深入学习和掌握,能够帮助专业人士和学生扩展网络知识,提高解决复杂网络问题的能力,并为将来的IT行业工作奠定扎实的基础。通过针对竞赛题目的实际操作演练,还能增强个人的实践技能和创新思维能力。
recommend-type

【VS2010模块化秘籍】:提升项目管理效率的10个技巧

# 1. VS2010模块化编程概述 在现代软件开发中,模块化编程已经成为提高代码质量和促进团队协作的关键技术之一。本章将介绍在Visual Studio 2010(VS2010)环境中如何理解和实施模块化编程。 ## 1.1 什么是模块化编程? 模块化编程是一种组织程序结构的方法,将程序分解为独立且可管理的模块,每个模块实现一个特定的功能。在V
recommend-type

数据分析师发展前景

<think>嗯,用户现在想了解数据分析师的职业发展和未来前景。根据之前的对话,用户是土木本科想转行,之前我建议过数据分析作为可能的方向之一,现在他可能想更深入了解这个领域的潜力。 首先,我需要参考之前提供的引用内容。引用1提到了数据分析师的职业路径,从专员到专家,还有技能提升的重要性。引用2和3强调了行业需求增长和技能的必要性,引用4则讨论了成为行业专家的长期发展优势。这些都需要整合到回答中。 用户的问题集中在职业前景和趋势,所以我要覆盖市场需求、职业阶段、技能要求、行业趋势和转行建议。考虑到用户是转行者,需要突出土木背景如何与数据分析结合,比如提到的BIM、GIS或者工程数据分析,这样
recommend-type

Elasticsearch及IK分词器安装包资源汇总

标题中提到的知识点包括Elasticsearch安装包和IK分词器,这是进行搜索引擎搭建和数据文本分析的重要组件。Elasticsearch是一个基于Lucene构建的开源搜索引擎,具有水平可伸缩性、高可用性和易用性的特点。它提供了全文搜索功能,同时支持结构化搜索和分析,常被用于大数据分析场景中。 描述中涉及的版本信息表明了所附的安装包和分词器支持不同版本的Elasticsearch。Elasticsearch版本6.x和7.x分别对应了两个主要的版本线,而IK分词器是专门为Elasticsearch设计的中文分词插件。 IK分词器是一款支持中文分词的扩展插件,可以根据中文语境进行智能分词,包括正向匹配、正向最大匹配和逆向最大匹配等算法,对中文文本进行处理。分词器的版本通常会与Elasticsearch的版本相匹配,以保证兼容性和最佳性能。 提到的logstash是与Elasticsearch配合使用的数据处理管道工具,负责收集、处理和转发数据。logstash可以作为事件的中介来处理各种来源的数据,然后将其发送到Elasticsearch进行存储。本压缩包中的logstash-6.4.3.tar.gz对应的版本表明了它的兼容性,适用于Elasticsearch 6.x版本。 压缩包文件名称列表中的文件包含了不同软件的多个版本。其中,“elasticsearch-head-master.zip”是一个可以对Elasticsearch进行可视化管理的Chrome插件,它提供了包括集群管理、索引管理、数据操作和查询在内的功能。 另外,“mysql-connector-java-5.1.41.jar”是一个MySQL数据库的Java驱动程序,用于连接Java应用程序和MySQL数据库,但这似乎与Elasticsearch及IK分词器直接关联不大,可能是一个辅助组件,用于在某些集成场景下将数据从MySQL迁移到Elasticsearch。 从标签内容来看,Elasticsearch被归类于源码软件、大数据和搜索引擎类别。它是一个重要的大数据处理组件,特别是在全文搜索和文本分析领域。在大数据背景下,Elasticsearch凭借其卓越的搜索和分析能力,已经成为企业构建和维护搜索引擎的首选技术之一。 总结来说,本次提供的压缩包包含了多个关键组件,它们共同支持构建一个功能强大的搜索引擎和数据分析平台。Elasticsearch自身及其配套的IK分词器、logstash和可视化插件elasticsearch-head,均对大数据和搜索领域有着重要意义。尽管这些工具具有复杂性,但它们的组合使用使得数据的索引、搜索、可视化和分析变得简单、快速和强大。
recommend-type

从零开始:Axure插件开发入门指南,构建自定义Chrome工具

# 摘要 随着原型设计工具Axure RP的广泛应用,定制化插件开发变得日益重要。本文旨在为开发者提供一个完整的Axure插件开发指南,从基础概念到环境搭建,再到核心编程和界面定制,最终实现交互逻辑与发布维护。通过详细解析插件的API、JavaScript编程、数据管理、界面设计及发布流程,本文帮助开发者深入理解并掌握Axure插件开发的关键技术,确保开发过程的高效性和插件的稳定运行。 # 关键字 Axur