结合异步迭代器实现 Node.js 流式数据复制

开发 前端
实现可读流到可写流数据复制,就是不断的读取->写入这个过程,那么你首先想到的是不是下面这样呢?代码看似很简单,结果却是很糟糕的,没有任何的数据积压处理。

[[422219]]

实现可读流到可写流数据复制,就是不断的读取->写入这个过程,那么你首先想到的是不是下面这样呢?代码看似很简单,结果却是很糟糕的,没有任何的数据积压处理。如果读取的文件很大了,造成的后果就是缓冲区数据溢出,程序会占用过多的系统内存,拖垮服务器上的其它应用,如果不明白的回顾下这篇文章 Node.js Stream 背压 — 消费端数据积压来不及处理会怎么样?。

  1. // 糟糕的示例,没有数据积压处理 
  2. readable.on('data', data => { 
  3.   writable.write(data) 
  4. }); 

类似以上的需求,推荐你用 pipe() 方法以流的形式完成数据的复制。

作为学习,结合异步迭代器以一种简单的方式实现一个类似于 pipe 一样的方法完成数据源到目标源的数据复制。

数据写入方法实现

_write 方法目的是控制可写流的数据写入,它返回一个 Promise 对象,如果可写流的 dest.write() 方法返回 true,表示内部缓冲区未满,继续写入。

当 dest.write() 方法返回 false 表示向流中写入数据超过了它所能处理的最大能力限制,此时暂停向流中写入数据,直到 drain 事件触发,表示缓冲区中的数据已排空了可以继续写入,再将 Promise 对象变为解决。

  1. function _write(dest, chunk) { 
  2.   return new Promise(resolve => { 
  3.     if (dest.write(chunk)) { 
  4.       return resolve(null); 
  5.     } 
  6.  
  7.     dest.once('drain', resolve); 
  8.   })   

结合异步迭代器实现

异步迭代器使从可读流对象读取数据变得更简单,异步的读取数据并调用我们封装的 _write(chunk) 方法写入数据,如果缓冲区空间已满,这里 await _write(dest, chunk) 也会等待,当缓冲区有空间可以继续写入了,再次进行读取 -> 写入。

  1. function myCopy(src, dest) { 
  2.   return new Promise(async (resolve, reject) => { 
  3.     dest.on('error', reject); 
  4.  
  5.     try { 
  6.       for await (const chunk of src) { 
  7.         await _write(dest, chunk); 
  8.       } 
  9.       resolve(); 
  10.     } catch (err) { 
  11.       reject(err); 
  12.     } 
  13.   }); 

使用如下所示:

  1. const readable = fs.createReadStream('text.txt'); 
  2. const writable = fs.createWriteStream('dest-text.txt'); 
  3. await myCopy(readable, writable); 

本文转载自微信公众号「Nodejs技术栈」,可以通过以下二维码关注。转载本文请联系Nodejs技术栈公众号。

 

责任编辑:武晓燕 来源: Nodejs技术栈
相关推荐

2021-03-04 23:12:57

Node.js异步迭代器开发

2020-12-08 06:28:47

Node.js异步迭代器

2021-04-06 10:15:29

Node.jsHooks前端

2022-05-05 08:02:44

MongoDBNode.js加密

2011-12-23 13:58:57

node.js

2021-07-15 10:15:52

Node.jsJSON前端

2021-05-18 09:01:39

Node.jsJSON文件

2013-11-01 09:34:56

Node.js技术

2021-03-16 16:16:41

GeneratorWebsockets前端

2015-03-10 10:59:18

Node.js开发指南基础介绍

2024-06-17 08:03:51

2021-07-16 04:56:03

NodejsAddon

2021-01-26 08:07:44

Node.js模块 Async

2021-03-09 08:03:21

Node.js 线程JavaScript

2020-10-12 08:06:28

HTTP 服务器证书

2021-09-03 13:42:54

Node.js异步性能

2011-09-08 13:46:14

node.js

2011-09-02 14:47:48

Node

2011-11-01 10:30:36

Node.js

2011-09-09 14:23:13

Node.js
点赞
收藏

51CTO技术栈公众号