Node streams流
前端那些年 人气:0Node中的streams流
streams流是Node中的最好的特性之一。它在我们的开发过程当中可以帮助我们做很多事情。比如通过流的方式梳理大量数据,或者帮我们分离应用程序。
和streams流相关的内容有哪些呢?大致有这么几点:
- 处理大量数据
- 使用管道方法
- 转换流
- 读写流
- 解耦I/O
转换流
Node中的流其实是允许我们进行异步编程的。最常见的就是转换流,它就像是一个接收输入并且产生输出的大黑盒子。
举个例子:
const through = require('through2') const upper = through((chunk, enc, cb) => { cb(null, chunk.toString().toUpperCase()) }) process.stdin.pipe(upper).pipe(process.stdout)
执行它,我们在终端输入的内容,它会转换成大写并且重新输出到终端。
through2模块在核心流的构造器上又加了一层。当我们创建upper时,我们给through传了一个回调函数进去,这个回调函数就是转换方法。流中的每段数据都将通过这个方法,chunk表示数据,enc表示数据的编码格式,cb是一个回调函数,我们执行它表示我们已经完成了数据处理,并且进行下一步处理。
使用through2模块进行处理数据,一方面可读性更强,另一方面,可以保持Node版本之前的行为一致。
创建
大多数情况下,当我们使用核心模块时,我们会直接使用。例如:
const fs = require('fs') const stream = require('stream')
但是经验告诉我们:不要直接使用核心流模块。我们可以使用readable-stream,虽然名字不一样,但是这确实可以保证我们在不同的Node版本之间保持很好的一致性。所以在代码中我们应该尽可能的使用readable-stream
const stream = require('readable-stream')
看这个例子:
const stream = require('readable-stream') const util = require('util') function MyTransform(opts){ stream.Transform.call(this,opts) } util.inherits(MyTransform,stream.Transform) MyTransform.prototype._transform = function(chunk,enc,cb){ cb(null,chunk.toString().toUpperCase()) } const upper = new MyTransform() process.stdin.pipe(upper).pipe(process.stdout)
在Node的早期版本中,这是创建流的标准方式。但是es6出现以后,有一种更简单的方法。
const {Transform} = require('readable-stream') class MyTransform extends Transform { _transform(chunk,enc,cb){ cb(null,chunk.toString().toUpperCase(),) } } const upper = new MyTransform() process.stdin.pipe(upper).pipe(process.stdout)
对象模式
如果我们的流不是返回的序列换的数据,一般是buffer或者string,我们需要将它转换成一个对象。但是我们需要知道具体传了多少数据过来。
默认情况下,当不使用对象模式时,流将在暂停前缓冲大约16KB的数据。使用对象模式时,当缓冲了16个对象后,它将开始暂停。
再来看一个例子:
const through = require('through2') const ndjson = require('ndjson') const xyz = through.obj(({ x, y }, enc, cb) => { cb(null, { z: x + y }) }) xyz.pipe(ndjson.stringify()).pipe(process.stdout) xyz.write({ x: 199, y: 3 }) xyz.write({ x: 10, y: 12 })
这个例子会打印下面的结果
我们用through2模块的obj方法创建了一个流。然后通过pipe方法write的信息进行stringify然后再传给process.stdout,最后返回了计算后的结果。
我们也可以使用readable-stream模块来实现这个:
const {Transform} = require('readable-stream') const {serialize} = require('ndjson') const xyz = Transform({ objMode:true, transform:({x,y},enc,cb)=>{ cb(null,{z:x+y}) } }) xyz.pipe(ndjson.stringify()).pipe(process.stdout) xyz.write({ x: 199, y: 3 }) xyz.write({ x: 10, y: 12 })
同样可以实现上面的效果。
最后
加载全部内容