Javascript pipe(stream of Node.js)和bl(BufferList)是如何协同工作的?
这实际上是Node.js教程([)中的第8个练习 目标: 编写一个程序,对作为第一个命令行参数提供给您的URL执行HTTP GET请求。从服务器收集所有数据(不仅仅是第一个“数据”事件),然后向控制台(stdout)写入两行数据 您写入的第一行应该是一个整数,表示从服务器接收的字符数。第二行应该包含服务器发送的完整字符串 这是我的解决方案(它通过了,但与官方解决方案相比看起来更难看) 官方解决方案:Javascript pipe(stream of Node.js)和bl(BufferList)是如何协同工作的?,javascript,node.js,stream,pipe,Javascript,Node.js,Stream,Pipe,这实际上是Node.js教程([)中的第8个练习 目标: 编写一个程序,对作为第一个命令行参数提供给您的URL执行HTTP GET请求。从服务器收集所有数据(不仅仅是第一个“数据”事件),然后向控制台(stdout)写入两行数据 您写入的第一行应该是一个整数,表示从服务器接收的字符数。第二行应该包含服务器发送的完整字符串 这是我的解决方案(它通过了,但与官方解决方案相比看起来更难看) 官方解决方案: var http = require('http') var bl = require('bl'
var http = require('http')
var bl = require('bl')
http.get(process.argv[2], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
data = data.toString()
console.log(data.length)
console.log(data)
}))
})
我很难理解官方解决方案是如何工作的。我主要有两个问题:
bl.end()
调用?我看不出哪里调用了bl.end()
bl github页面的这一部分或多或少地回答了您的问题: 在构造函数中给它一个回调,并像 海螺流:
const bl = require('bl')
, fs = require('fs')
fs.createReadStream('README.md')
.pipe(bl(function (err, data) { // note 'new' isn't strictly required
// `data` is a complete Buffer object containing the full data
console.log(data.toString())
}))
请注意,当您像这样使用回调方法时,结果
数据参数是数据库中所有缓冲区对象的串联
如果您想避免这种连接的开销(在
极端性能意识的情况下),然后避免回调
方法,只需听“end”,就像标准流一样
您正在将a传递给bl,这基本上是一个函数,当它有数据流要处理时,它将调用该函数。因此,数据目前尚未定义…它只是一个参数名,稍后将用于传递GET调用中的文本以进行打印
我相信不必调用bl.end(),因为让它运行并没有实际的性能开销,但我可能错了。我已经阅读了
bl
库和的源代码
BufferList
是一个自定义的双工流,既可读又可写。当您运行readableStream.pipe(BufferList)
时,默认情况下,当源流发出end()
时,将在BufferList上调用end()
作为目标
请参阅BufferList.prorotype.end的下面部分:
BufferList.prototype.end = function (chunk) {
DuplexStream.prototype.end.call(this, chunk)
if (this._callback) {
this._callback(null, this.slice())
this._callback = null
}
}
因此,传递到BufferList
的回调将在BufferList
从源流接收到所有数据后调用,调用this.slice()
将返回连接BufferList
中所有缓冲区的结果,数据
参数来自何处
var request=require('request')
request(process.argv[2],function(err,response,body){
console.log(body.length);
console.log(body);
})
你可以看看这个方法来解决上面的练习,
p、 s的请求是第三方模块,尽管谢谢!事实上,我不好,我应该更仔细地阅读文档。1)数据参数用作输出参数,bl不要求它是bl的实例。(这里的描述误导了我2)对于end()调用,它确实应该由stream.pipe()调用
BufferList.prototype.end = function (chunk) {
DuplexStream.prototype.end.call(this, chunk)
if (this._callback) {
this._callback(null, this.slice())
this._callback = null
}
}
var request=require('request')
request(process.argv[2],function(err,response,body){
console.log(body.length);
console.log(body);
})