Nodejs正在侦听来自http.get()的数据事件的响应流

Nodejs Listening to response stream on data event from http.get()

本文关键字:数据 事件 响应 get http Nodejs      更新时间:2023-09-26

我正在学习Node.js。为此,我使用了有用的nodeschool.io研讨会。我现在正在阅读学习节点研讨会。

在http客户端和http收集部分我遇到了一个问题。尽管我读过它们和node.js上的api文档。第一个挑战是;"将响应中的每个"数据"事件的字符串内容写入控制台(stdout)的新行。"。它在https收集部分中说,"从服务器收集所有数据(不仅仅是第一个"数据"活动)…"并引用第一个,因为它没有收集所有数据。不是

var allData = "";
response.setEncoding('utf8');
response.on('data', function(data){
    allData = concat(allData, data);
}

能够从响应中收集所有数据。

到目前为止,我已经了解了异步的本质,当异步http.get()完成时,将调用下面的第一个回调。或者我错了http.get()不是异步的。

var http = require('http');
var urlString = process.argv[2];
http.get(urlString, function callback (response) {
    response.setEncoding('utf8');
    response.on('data', console.log);
    response.on('error', console.error);
})

执行此代码时会发生什么。回调是否等待http.get()完成并提供response,因此http.get()是异步的?如果是,则在response.on(..)行正在侦听的事件被激发时,在其创建之后。

这难道不是在创建response时执行的一个连续过程吗?在这种情况下,callback不应该等待http.get()完成执行,以便事件侦听器可用于response对象触发的事件?

一种解释可以是:;http.get()创建一个响应对象以供服务器写入并完成。因此,它通过创建响应对象完成了它的工作,从现在起,服务器可能会开始写入该响应流,并且回调已经开始,继续侦听响应流中的"数据"事件,以查找服务器向其写入任何数据时激发的"数据"事件。这在逻辑上是可能的。

这是node.js的一个常见功能流式传输的示例。

Http.get确实在调用回调之前完成了执行(通过创建流)。它是仍在回调中处理的流。http.get的最终结果是在接收到完整响应之前仍在更新的流对象。

考虑回调的方法不是作为一个在父函数执行完毕时执行的函数,而是作为另一个函数的参数的函数。从理论上讲,没有什么可以阻止父级在其执行周期的任何时候执行回调。node.js中的约定恰好是在父级完成后执行回调。

函数回调作为参数传递到函数http.get中是正确的,因此它可以访问在执行http.get期间创建的响应对象。然而,同样发生的是,响应是一个流,这意味着它会不断更新,直到完成。

这是的操作顺序

  1. http.get调用外部资源
  2. http.get将响应对象创建为流,并在数据来自外部资源时对其进行更新
  3. 每次更新响应对象时,它都会发出一个"数据"事件
  4. 函数回调包含一个侦听器(response.on),每当抛出"数据"事件时,该侦听器就会被激活

下面是一个创建流并将其传递到回调的函数示例

function myAsyncFunction(callback){
    var result = createStream();  // perform processing to create a streaming object
    // at this point, the parent function is done so lets execute the callback
    callback(result);
}
function processStream(example){
    example.on('data', function(chunk){
        console.log('chunk received' + chunk);
    });
    example.on('end', function(){
        console.log('streaming is complete');
    });
}
myAsyncFunction(processStream);