Node中的streams流
streams流是Node中的最好的特性之一。它在我们的开发过程当中可以帮助我们做很多事情。比如通过流的方式梳理大量数据,或者帮我们分离应用程序。
和streams流相关的内容有哪些呢?大致有这么几点:
- 处理大量数据
- 使用管道方法
- 转换流
- 读写流
- 解耦I/O
处理大量数据
有一个很经典的问题:计算npm所有可使用的Node模块。
npm公开了一个HTTP节点,我们可以以JSON的形式获取npm注册表内容的全部内容。我们可以用一个请求试一下:
代码语言:javascript复制curl https://skimdb.npmjs.com/registry/_changes?inclued_docs=true
然后我们可以在终端看到不停的打印一个JSON。
我们可以写一段代码实现它。
代码语言:javascript复制var request = require('request')
var npmDb = 'https://skimdb.npmjs.com'
var registryUrl = `${npmDb}registry/_changes?_include_docs=true`
request(registryUrl, (err, data) => {
if (err) console.log('err:', err)
const numOfLine = data.split('n').length 1
console.log('total modules on npm is:' numOfLine)
})
如果我们执行上面的代码,我们会发现两个问题:
第一,这个请求要花很长时间。第二,请求的过程中有可能会报错。
这是因为,数据量太多,需要多一些内存去缓冲所有的数据。
尝试读写流
我们可以先用读写流来体会一下streams的用法。
代码语言:javascript复制// read.js
const fs = require('fs')
const rs = fs.createReadStream(__filename)
console.log('filename--', __filename)
rs.on('data', (data) => {
console.log('读的数据:', data)
})
rs.on('end', () => {
console.log('完成读写---->')
})
执行这个代码,它会将当前文件中的内容数据显示到终端上。
流的使用规则
通常情况下,我们创建流的时候应该尽量避免直接使用内置的streams模块。因为不同版本下它们的表现结果可能不太一致。我们可以使用与核心流模块相关的其他模块,比如fs,这样在未来的代码维护中,我们可以相对轻松一些。
流的类型
如果我们想创建一个让别人可以读的流,我们就用需要使用可读流。可读流的一个例子就是从硬盘上读取文件。
如果我们想创建一个可以写入文件的流,我们就需要使用可写流。可写流的一个例子就是往硬盘上存储文件。
有时候我们想要创建一个既可以读又可以写的流。这时候我们就需要使用双工流。双工流的一个例子就是TCP network。我们即可以从network上读取数据,又可以回复数据给它。
还有一种特殊的双工流叫转换流。它可以转换写入其中的数据,并使转换后的数据可从流中读出。转换流的一个例子GZIP。