Nodejs从http.get()收听数据事件的响应流

时间:2014-11-11 21:05:32

标签: javascript node.js asynchronous

我正在研究Node.js.为此,我使用有用的nodeschool.io研讨会。我现在正在阅读learnyounode研讨会。

在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()的作用是创建一个响应对象,服务器在其上写入并完成。所以它通过创建响应对象完成了它的工作,从现在开始,服务器可能会开始写入这个响应流,并且回调已经开始,正在监听响应流的数据'服务器向其写入任何数据时触发的事件。这在逻辑上是可能的。

1 个答案:

答案 0 :(得分:4)

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

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

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

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

以下是操作顺序

  1. http.get调用外部资源。
  2. http.get将响应对象创建为流,并在数据从外部资源进入时更新它
  3. 每次更新响应对象时,都会发出"数据"事件
  4. 函数回调包含一个监听器(response.on),只要"数据"事件被抛出。
  5. 这是一个创建流并将其传递给回调

    的函数示例
    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);