WritableStream
注意:此功能在Web Workers中可用。
Streams API的WritableStream
接口为将流式数据写入目标(称为接收器)提供了一种标准抽象。此对象具有内置的反压和排队功能。
WritableStream
是一个可传输对象。
构造函数
WritableStream()
-
创建一个新的
WritableStream
对象。
实例属性
WritableStream.locked
只读-
一个布尔值,指示
WritableStream
是否锁定到写入器。
实例方法
WritableStream.abort()
-
中止流,表示生产者无法再成功写入流,并且它将立即进入错误状态,并丢弃任何排队的写入操作。
WritableStream.close()
-
关闭流。
WritableStream.getWriter()
-
返回一个新的
WritableStreamDefaultWriter
实例,并将流锁定到该实例。在流被锁定期间,在释放此写入器之前,无法获取其他写入器。
示例
以下示例说明了此接口的几个特性。它展示了使用自定义接收器和 API 提供的排队策略创建WritableStream
的过程。然后,它调用一个名为sendMessage()
的函数,并将新创建的流和一个字符串作为参数传递。在该函数内部,它调用流的getWriter()
方法,该方法返回一个WritableStreamDefaultWriter
实例。使用forEach()
调用将字符串的每个块写入流。最后,write()
和close()
返回一些承诺,这些承诺被处理以处理块和流的成功或失败。
js
const list = document.querySelector("ul");
function sendMessage(message, writableStream) {
// defaultWriter is of type WritableStreamDefaultWriter
const defaultWriter = writableStream.getWriter();
const encoder = new TextEncoder();
const encoded = encoder.encode(message);
encoded.forEach((chunk) => {
defaultWriter.ready
.then(() => defaultWriter.write(chunk))
.then(() => {
console.log("Chunk written to sink.");
})
.catch((err) => {
console.log("Chunk error:", err);
});
});
// Call ready again to ensure that all chunks are written
// before closing the writer.
defaultWriter.ready
.then(() => {
defaultWriter.close();
})
.then(() => {
console.log("All chunks written");
})
.catch((err) => {
console.log("Stream error:", err);
});
}
const decoder = new TextDecoder("utf-8");
const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 1 });
let result = "";
const writableStream = new WritableStream(
{
// Implement the sink
write(chunk) {
return new Promise((resolve, reject) => {
const buffer = new ArrayBuffer(1);
const view = new Uint8Array(buffer);
view[0] = chunk;
const decoded = decoder.decode(view, { stream: true });
const listItem = document.createElement("li");
listItem.textContent = `Chunk decoded: ${decoded}`;
list.appendChild(listItem);
result += decoded;
resolve();
});
},
close() {
const listItem = document.createElement("li");
listItem.textContent = `[MESSAGE RECEIVED] ${result}`;
list.appendChild(listItem);
},
abort(err) {
console.log("Sink error:", err);
},
},
queuingStrategy,
);
sendMessage("Hello, world.", writableStream);
您可以在我们的简单写入器示例中找到完整代码。
背压
由于 API 中支持背压的方式,因此其在代码中的实现可能不那么明显。要了解背压是如何实现的,请查找三件事
highWaterMark
属性,在使用new CountQueuingStrategy
创建计数策略时设置,它设置了WritableStream
实例在单个write()
操作中处理的最大数据量。在此示例中,它是可以发送到defaultWriter.write()
(在sendMessage
函数中)的最大数据量。defaultWriter.ready
属性返回一个承诺,当接收器(WritableStream
构造函数的第一个属性)完成数据写入时,该承诺将被解决。数据源可以使用defaultWriter.write()
写入更多数据,或者调用defaultWriter.close()
,如上例所示。过早调用close()
可能会阻止数据写入。这就是为什么示例会调用两次defaultWriter.ready
的原因。- 接收器的
write()
方法返回的Promise
告诉WritableStream
及其写入器何时解决defaultWriter.ready
。
规范
规范 |
---|
流标准 # ws-class |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。
另请参阅
- WHATWG 流可视化工具,用于对可读、可写和转换流进行基本可视化。