Chrome 如何在Reader“挂起”时中断它(需要在www.example.com()上设置超时Reader.read)

pkwftd7m  于 2023-05-27  发布在  Go
关注(0)|答案(2)|浏览(264)

此问题与使用Chrome串行API时发生的情况有关,但可能与任何ReadableStream相关。我研究了文档,可能错过了一些功能或模式。
一个简单的程序在Chrome浏览器中运行,访问CW键控器(基于Arduino,但这并不重要)。
应用程序向键控器发送命令,并期望两个二进制字节或一个字符串作为响应(特定格式取决于发送的命令,并不重要)。
如果串行设备(不是USB/串行适配器,而是Arduino)由于任何原因错过了命令,则永远不会发送响应,并且下面的函数expectResponse()永远不会返回任何数据,也不会抛出任何异常。因此,阅读器保持锁定,ReadableStream因此无法关闭,因此串行端口也无法关闭。
此外,取决于应用结构,在其他命令成功发送到键控器的情况下,可能无法读取第二响应,因为第一读取器阻止流,并且直到它被释放,才能创建新的读取器。

async function expectResponse( serialPort ) {
   const reader = serialPort.readable.getReader() ;
   let { value, done } = await reader.read() ; // this never returns because no data arrive, not possible to "break"
}

async function disconnect( serialPort ) {
   // ... some cleanup ...
   // naive attempt to unlock ReadableStream before closing 
   await serialPort.readable.getReader().releaseLock() // this will throw exception - cannot create  new reader while another one is still active and locks the stream
   // ...
   await serialPort.close(); // this will throw exception - cannot close port because readable stream is locked
}

serialPortnavigator.serial.requestPort()返回的对象
我确信我一定错过了API文档中的一些重要内容(ReadableStreamReader API,而不是Serial API),但我没有找到解决方案。
P.S.在真实的应用程序中serialPort是一个全局变量,但这并不重要,不是吗?

fivyi3re

fivyi3re1#

我不认为ReadableStream内置了超时。
我会使用Promise.race,另一个promise是你的timeout:

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

Promise.race监视promise的竞争,根据它给予的数组中promise的第一个结算来结算它的promise。因此,如果read的promise在timeout promise拒绝之前被满足(或拒绝),则read的结算决定race promise的结算。否则,race promise将根据timeout promise的结算(在本例中为rejection)进行结算。

mpbci0fu

mpbci0fu2#

可以“中断”await操作:
根据文档,如果调用reader.releaseLock()await reader.read()将抛出TypeError。(例如setTimeout
文档:https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultReader/read

try {
    await reader.read();
} catch(e) {
    console.log("you got out from await");
}

setTimeout(function() {
    reader.releaseLock();
}, TIMEOUT);

相关问题