流 API:可以撤消 .pipeTo() 吗?
Streams API: possible to undo .pipeTo()?
Streams API provides a neat way of piping a ReadableStream
to a WritableStream
using readableStream.pipeTo(writableStream)
。这似乎比获取 readableStream.getReader()
并将其手动粘贴到 writableStream.getWriter()
或直接粘贴到基础功能更方便。
我有一个用例,向我提供了一个 ReadableStream
对象,该对象最终可能需要“消失”并由新的 ReadableStream
对象替换。最好使用单个自定义 WritableStream
来包装这些 ReadableStream
对象与之接口的功能,并根据需要将它们连接在一起,但还没有找到如何“撤消”管道过程.
问:是否可以“撤消”/“破坏”/“拆卸”使用 .pipeTo()
创建的管道,或者管道是否“永久”且不适用于此用例?
使用 Serial API 的示例,我希望能够在其中重复调用 doConnectPort()
然后 doDisconnectPort()
:
var customWritable = new WritableStream(…);
var port;
async function doConnectPort() {
port = await navigator.serial.requestPort();
await port.open({ baudrate: …});
await port.readable.pipeTo(customWritable);
}
async function doDisconnectPort() {
// What to do here? Can't close the port yet—port.readable is still locked!
await port.close();
}
目前,我手动将东西粘在一起并在需要断开端口时进行清理:
var port;
var portReader;
async function doConnectPort() {
port = await navigator.serial.requestPort();
await port.open({ baudrate: …});
portReader = port.readable.getReader();
while (true) {
const { value, done } = await portReader.read();
if (done) {
break;
}
// do something with value
}
}
async function doDisconnectPort() {
await portReader.cancel();
await portReader.releaseLock();
await port.close();
}
您可以在 pipeTo
的选项对象的 signal
中传递一个 AbortSignal。
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();
}
};
}
<label>Abort pipe<input type="checkbox" checked></label><br>
<button id="btn">new test</button>
Streams API provides a neat way of piping a ReadableStream
to a WritableStream
using readableStream.pipeTo(writableStream)
。这似乎比获取 readableStream.getReader()
并将其手动粘贴到 writableStream.getWriter()
或直接粘贴到基础功能更方便。
我有一个用例,向我提供了一个 ReadableStream
对象,该对象最终可能需要“消失”并由新的 ReadableStream
对象替换。最好使用单个自定义 WritableStream
来包装这些 ReadableStream
对象与之接口的功能,并根据需要将它们连接在一起,但还没有找到如何“撤消”管道过程.
问:是否可以“撤消”/“破坏”/“拆卸”使用 .pipeTo()
创建的管道,或者管道是否“永久”且不适用于此用例?
使用 Serial API 的示例,我希望能够在其中重复调用 doConnectPort()
然后 doDisconnectPort()
:
var customWritable = new WritableStream(…);
var port;
async function doConnectPort() {
port = await navigator.serial.requestPort();
await port.open({ baudrate: …});
await port.readable.pipeTo(customWritable);
}
async function doDisconnectPort() {
// What to do here? Can't close the port yet—port.readable is still locked!
await port.close();
}
目前,我手动将东西粘在一起并在需要断开端口时进行清理:
var port;
var portReader;
async function doConnectPort() {
port = await navigator.serial.requestPort();
await port.open({ baudrate: …});
portReader = port.readable.getReader();
while (true) {
const { value, done } = await portReader.read();
if (done) {
break;
}
// do something with value
}
}
async function doDisconnectPort() {
await portReader.cancel();
await portReader.releaseLock();
await port.close();
}
您可以在 pipeTo
的选项对象的 signal
中传递一个 AbortSignal。
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();
}
};
}
<label>Abort pipe<input type="checkbox" checked></label><br>
<button id="btn">new test</button>