Javascript 我怎么能打断读者的话;挂起;(Reader.read()需要超时)

Javascript 我怎么能打断读者的话;挂起;(Reader.read()需要超时),javascript,google-chrome,serial-port,webapi,Javascript,Google Chrome,Serial Port,Webapi,这个问题与使用Chrome串行API时发生的情况有关,但可能与任何ReadableStream有关。我研究了文档,可能遗漏了一些特性或模式 一个简单的程序正在Chrome浏览器中运行,访问CW键控器(基于Arduino,但这并不重要) 应用程序向键控器发送命令,并期望两个二进制字节或字符串作为响应(特定格式取决于发送的命令,并不重要) 如果串行设备(不是USB/串行适配器,而是Arduino)由于任何原因错过了命令,则不会发送响应,下面的函数expectResponse()将不会返回任何数据,也

这个问题与使用Chrome串行API时发生的情况有关,但可能与任何ReadableStream有关。我研究了文档,可能遗漏了一些特性或模式

一个简单的程序正在Chrome浏览器中运行,访问CW键控器(基于Arduino,但这并不重要)

应用程序向键控器发送命令,并期望两个二进制字节或字符串作为响应(特定格式取决于发送的命令,并不重要)

如果串行设备(不是USB/串行适配器,而是Arduino)由于任何原因错过了命令,则不会发送响应,下面的函数
expectResponse()
将不会返回任何数据,也不会引发任何异常。因此,读卡器保持锁定状态,因此无法关闭ReadableStream,因此也无法关闭串行端口

此外,取决于应用程序结构,在其他命令成功发送到键控器的情况下,可能不可能读取第二响应,因为第一读取器阻止流,并且在释放流之前,无法创建新读取器


异步函数expectResponse(串行端口){
const reader=serialPort.readable.getReader();
让{value,done}=wait reader.read();//这永远不会返回,因为没有数据到达,不可能“中断”
}
异步功能断开(串行端口){
//…清理一下。。。
//在关闭之前解锁ReadableStream的天真尝试
等待serialPort.readable.getReader().releaseLock()//这将引发异常-当另一个读取器仍处于活动状态时无法创建新读取器并锁定流
// ...
等待serialPort.close();//这将引发异常-无法关闭端口,因为可读流已锁定
}
serialPort
是由
navigator.serial.requestPort()返回的对象

我确信我一定错过了API文档中的一些重要内容(
ReadableStream
Reader
API,而不是
Serial
API),但我没有找到解决方案


另外,在真正的应用程序中,
serialPort
是一个全局变量,但这并不重要,不是吗?

我认为,
ReadableStream
没有内置超时

我会用另一个承诺作为你的超时:

let { value, done } = await Promise.race([
    reader.read(),
    new Promise((_, reject) => setTimeout(reject, TIMEOUT, new Error("timeout")))
]);
(您可能会将该
新承诺
代码放在实用函数中。)

Promise.race
监视promises竞赛,根据在您给它的数组中看到的承诺的第一次结算来结算它的承诺。因此,如果
read
的承诺在超时承诺拒绝之前得到履行(或拒绝),那么
read
的结算决定了
比赛
承诺的结算。否则,
race
承诺将基于超时承诺的结算(在本例中为拒绝)进行结算