
实现可读流到可写流数据复制,结合据复就是异步不断的读取->写入这个过程,那么你首先想到的迭代是不是下面这样呢?代码看似很简单,结果却是器实很糟糕的,没有任何的式数数据积压处理。如果读取的结合据复文件很大了,造成的异步后果就是缓冲区数据溢出,程序会占用过多的迭代系统内存,拖垮服务器上的器实其它应用,IT技术网如果不明白的式数回顾下这篇文章 Node.js Stream 背压 — 消费端数据积压来不及处理会怎么样?。
// 糟糕的结合据复示例,没有数据积压处理 readable.on(data,异步 data => { writable.write(data) });类似以上的需求,推荐你用 pipe() 方法以流的迭代形式完成数据的复制。
作为学习,器实结合异步迭代器以一种简单的式数方式实现一个类似于 pipe 一样的方法完成数据源到目标源的数据复制。
_write 方法目的是控制可写流的数据写入,它返回一个 Promise 对象,如果可写流的 dest.write() 方法返回 true,云服务器提供商表示内部缓冲区未满,继续写入。
当 dest.write() 方法返回 false 表示向流中写入数据超过了它所能处理的最大能力限制,此时暂停向流中写入数据,直到 drain 事件触发,表示缓冲区中的数据已排空了可以继续写入,再将 Promise 对象变为解决。
function _write(dest, chunk) { return new Promise(resolve => { if (dest.write(chunk)) { return resolve(null); } dest.once(drain, resolve); }) }异步迭代器使从可读流对象读取数据变得更简单,异步的读取数据并调用我们封装的 _write(chunk) 方法写入数据,如果缓冲区空间已满,这里 await _write(dest, chunk) 也会等待,当缓冲区有空间可以继续写入了,再次进行读取 -> 写入。
function myCopy(src, dest) { return new Promise(async (resolve, reject) => { dest.on(error, reject); try { for await (const chunk of src) { await _write(dest, chunk); } resolve(); } catch (err) { reject(err); } }); }使用如下所示:
const readable = fs.createReadStream(text.txt); const writable = fs.createWriteStream(dest-text.txt); await myCopy(readable, writable);本文转载自微信公众号「Nodejs技术栈」,可以通过以下二维码关注。转载本文请联系Nodejs技术栈公众号。
