我有一个 Web 串行端口,我想从中读取一些数据。我想使用TransformStream
s 来做一些处理(例如将字节解码为字符串,分离出逻辑消息等),通过使用pipeThrough
来转换数据。但是,一旦我这样做了,我就不能再通过调用reader.releaseLock()
. 我在这里做错了什么?
这段代码按我的预期工作(在安全上下文中在浏览器中运行而没有依赖项):
async serialTestWorking() {
const port = await navigator.serial.requestPort();
await port.open({baudRate: 9600});
console.log("Is locked after open?", port.readable.locked);
// Prints "Is locked after open? false"
let reader = port.readable.getReader();
console.log("Is locked after getReader?", port.readable.locked);
// Prints "Is locked after getReader? true"
reader.releaseLock();
console.log("Is locked after releaseLock?", port.readable.locked);
// Prints "Is locked after releaseLock? false"
await port.close();
console.log("Port closed");
// Prints "Port closed"
}
但是,如果我pipeThrough
过去通过 do-nothing 发送输出TransformStream
,一切都会崩溃。锁没有被释放,releaseLock
最终close
无法工作。
async serialTestBroken() {
const port = await navigator.serial.requestPort();
await port.open({baudRate: 9600});
console.log("Is locked after open?", port.readable.locked);
// Prints "Is locked after open? false"
let reader = port.readable.pipeThrough(new TransformStream()).getReader();
console.log("Is locked after getReader?", port.readable.locked);
// Prints "Is locked after getReader? true"
reader.releaseLock();
console.log("Is locked after releaseLock?", port.readable.locked);
// Prints "Is locked after releaseLock? true"
await port.close();
console.log("Port closed");
// Doesn't make it to the log line
//throws "TypeError: Failed to execute 'close' on 'SerialPort': Cannot cancel a locked stream"
}
我在这里做错了什么?释放锁TransformStream
真的不会向上游传播吗?我是否必须跟踪管道中每个变压器的实例,以便确保将它们全部解锁?
流规范说,管道在管道操作期间锁定可读和可写流。
管道锁定可读和可写流,防止它们在管道操作期间被操纵。这允许实现执行重要的优化,例如直接将数据从底层源传输到底层接收器,同时绕过许多中间队列。
是否有其他方式我必须表明“管道操作”已完成?