Streams API:可以撤消 .pipeTo() 吗?

chr*_*hvz 2 javascript serial-port whatwg-streams-api

Streams APIReadableStream提供了一种通过管道将 a 传送到WritableStreamusing的巧妙方法readableStream.pipeTo(writableStream)。这似乎比获取readableStream.getReader()并手动将其粘合到writableStream.getWriter()或直接粘合到底层功能更方便。

\n

我有一个用例,其中向我提供了一个ReadableStream对象,该对象最终可能需要“消失”并被新ReadableStream对象替换。最好使用单个自定义WritableStream来包装这些对象所连接的功能,ReadableStream并根据需要将它们通过管道连接在一起,但还没有找到如何“撤消”管道过程。

\n

问:是否可以“撤消”/“中断”/“拆卸”使用 创建的管道.pipeTo(),或者管道是否“永久”且不适合此用例?

\n

使用Serial API 的示例,我希望能够调用doConnectPort()然后doDisconnectPort()重复:

\n
var customWritable = new WritableStream(\xe2\x80\xa6);\nvar port;\n\nasync function doConnectPort() {\n  port = await navigator.serial.requestPort();\n  await port.open({ baudrate: \xe2\x80\xa6});\n  await port.readable.pipeTo(customWritable);\n}\n\nasync function doDisconnectPort() {\n  // What to do here? Can\'t close the port yet\xe2\x80\x94port.readable is still locked!\n  await port.close();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

目前,我手动将东西粘合在一起,并在需要断开端口时进行清理:

\n
var port;\nvar portReader;\n\nasync function doConnectPort() {\n  port = await navigator.serial.requestPort();\n  await port.open({ baudrate: \xe2\x80\xa6});\n  portReader = port.readable.getReader();\n  while (true) {\n    const { value, done } = await portReader.read();\n    if (done) {\n      break;\n    }\n    // do something with value\n  }\n}\n\nasync function doDisconnectPort() {\n  await portReader.cancel();\n  await portReader.releaseLock();\n  await port.close();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Kai*_*ido 5

您可以在选项对象.pipeTosignal

const btn = document.querySelector( "button" );
const checkbox = document.querySelector( "input" );

if( !ReadableStream.prototype.pipeTo ) {
  console.warn( "Your browser doesn't support pipeTo" );
}
else {

btn.onclick = (evt) => {

  console.clear( "" );
  const blob = new Blob( [ "hello" ] );
  const readable = blob.stream();
  const target = new TransformStream();
  const abort_controller = new AbortController();

  target.readable.getReader().read().then( console.log );

  readable.pipeTo( target.writable, { signal: abort_controller.signal } )
    .catch( console.error )

  if( checkbox.checked ) {
    abort_controller.abort();
  }
  
};

}
Run Code Online (Sandbox Code Playgroud)
<label>Abort pipe<input type="checkbox" checked></label><br>
<button id="btn">new test</button>
Run Code Online (Sandbox Code Playgroud)