WritableStream - 提供了用于将流数据写入目标的标准抽象
这是一个实验中的功能
此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。
WritableStream
是 Streams API 的接口,提供了用于将流数据写入目标(称为接收器)的标准抽象。该对象带有内置的反压和排队。
构造函数
WritableStream()
创建一个新的 WritableStream
对象。
属性
WritableStream.locked
只读
一个布尔值,指示 WritableStream
是否已锁定到写入器。
方法
WritableStream.abort()
中止该流,表明生产者无法再成功写入该流,并且应立即将其移至错误状态,并丢弃所有排队的写操作。
WritableStream.close()
关闭流。
WritableStream.getWriter()
返回一个新的 WritableStreamDefaultWriter
实例,并将流锁定到该实例。流被锁定后,在释放该写入器之前,无法再获取其他写入器。
实例
以下实例说明了此接口的一些功能。它显示了使用自定义接收器和 API 提供的排队策略创建 WritableStream
的过程。然后,它调用一个名为 sendMessage()
的函数,传递新创建的流和一个字符串。在此函数内,它调用流的 getWriter()
方法,该方法返回一个 WritableStreamDefaultWriter
的实例。接着调用 forEach()
将字符串的每个块写入流中。最后,write()
和 close()
返回处理块和流为成功或失败的承诺。
const list = document.querySelector('ul');
function sendMessage(message, writableStream) {
// defaultWriter 的类型为 WritableStreamDefaultWriter
const defaultWriter = writableStream.getWriter();
const encoder = new TextEncoder();
const encoded = encoder.encode(message, { stream: true });
encoded.forEach((chunk) => {
defaultWriter.ready
.then(() => {
return defaultWriter.write(chunk);
})
.then(() => {
console.log("块写入接收器。");
})
.catch((err) => {
console.log("块错误:", err);
});
});
// 在关闭写入器之前,再次调用就绪以确保所有块均已写入。
defaultWriter.ready
.then(() => {
defaultWriter.close();
})
.then(() => {
console.log("所有的块已写入。");
})
.catch((err) => {
console.log("流错误:", err);
});
}
const decoder = new TextDecoder("utf-8");
const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 1 });
let result = "";
const writableStream = new WritableStream({
// 实现接收器
write(chunk) {
return new Promise((resolve, reject) => {
var buffer = new ArrayBuffer(2);
var view = new Uint16Array(buffer);
view[0] = chunk;
var decoded = decoder.decode(view, { stream: true });
var listItem = document.createElement('li');
listItem.textContent = "块解码:" + decoded;
list.appendChild(listItem);
result += decoded;
resolve();
});
},
close() {
var listItem = document.createElement('li');
listItem.textContent = "[收到消息] " + result;
list.appendChild(listItem);
},
abort(err) {
console.log("接收器错误:", err);
}
}, queuingStrategy);
sendMessage("Hello, world.", writableStream);
您可以在我们的简单写入器实例中找到完整的代码。
反压
由于 API 中对反压的支持方式,它在代码中的实现可能不太直观。要了解反压力是如何实现的,请看以下三点:
- 在创建计数策略时设置的
highWaterMark
属性(第 35 行)设置了WritableStream
实例将在单个write()
操作中处理的最大数据量。在此实例中,它是指可以发送到defaultWriter.write()
(第 11 行)的最大数据量。 defaultWriter.ready
属性返回一个承诺,该承诺将在接收器(WritableStream
构造函数的第一个属性)完成写入数据后解析。数据源可以写入更多数据(第 9 行)或调用close()
(第 24 行)。太早调用close()
可能会阻止数据写入。这就是为什么该实例两次调用defaultWriter.ready
(第 9 和 22 行)的原因。- 接收器的
write()
方法(第 40 行)返回的Promise
告诉WritableStream
及其写入器何时解析defaultWriter.ready
。
规范
规范 | 状态 | 备注 |
---|---|---|
Streams WritableStream 的定义 |
现行的标准 | 初始定义。 |
桌面浏览器兼容性
特性 | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
基础支持 | 59 | 16 | 不支持 | 不支持 | 47 | 未知 |
WritableStream() 构造函数 | 59 | 16 | 不支持 | 不支持 | 47 | 未知 |
abort | 59 | 16 | 不支持 | 不支持 | 47 | 未知 |
getWriter | 59 | 16 | 不支持 | 不支持 | 47 | 未知 |
locked | 59 | 16 | 不支持 | 不支持 | 47 | 未知 |
移动浏览器兼容性
特性 | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
基础支持 | 59 | 59 | 未知 | 不支持 | 未知 | 44 | 未知 |
WritableStream() 构造函数 | 59 | 59 | 未知 | 不支持 | 未知 | 44 | 未知 |
abort | 59 | 59 | 未知 | 不支持 | 未知 | 44 | 未知 |
getWriter | 59 | 59 | 未知 | 不支持 | 未知 | 44 | 未知 |
locked | 59 | 59 | 未知 | 不支持 | 未知 | 44 | 未知 |
相关链接
- WHATWG 流视图,用于可读,可写和转换流的基本可视化。