【问题标题】:Nodejs Listening to response stream on data event from http.get()Nodejs从http.get()监听数据事件的响应流
【发布时间】:2015-01-08 13:44:49
【问题描述】:

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

在 http 客户端和 http collect 部分我遇到了问题。尽管我已经阅读了它们和 node.js 上的 api 文档。第一个挑战是; “将响应中每个“数据”事件的字符串内容写入控制台上的新行(标准输出)。”。它在 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()完成执行,以便事件监听器可用于@触发的事件987654332@对象?

可以这样解释; http.get() 做了什么来创建一个响应对象到服务器写入并完成。所以它通过创建响应对象完成了它的工作,从现在开始,服务器可能会开始写入这个响应流,并且回调已经开始,在服务器写入任何位数据时监听“数据”事件的响应流给它。这在逻辑上是可能的。

【问题讨论】:

  • allData 的范围不应是回调的本地范围。
  • 相应更新。

标签: javascript node.js asynchronous


【解决方案1】:

这是 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);

【讨论】:

  • 所以,你的意思是函数回调不会等待 http.get 完成,就像我在 fs.readdir 等其他一些异步函数中看到的那样,在这种情况下,回调只在 fs.readdir 之后调用读完。有什么区别以及何时知道是这种情况?
  • 在这种情况下,http.get 确实在调用回调之前完成执行。但是,http.get 的最终结果是在收到完整响应之前仍在更新的流对象。
  • 顺便说一句,考虑回调的方式不是作为在父函数执行完毕时执行的函数,而是作为另一个函数的参数的函数。从理论上讲,没有什么可以阻止父级在其执行周期中的任何时间执行回调。 node.js 中的约定恰好是在父级完成后执行回调。
  • 我明白了。使用函数作为参数定义异步函数的人可以将回调参数不是在父定义的末尾而是在末尾以上的任何位置调用。
  • 不完全是。 Http.get 在调用回调之前完成执行(通过创建流)。它是回调中仍在处理的流。
猜你喜欢
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 2019-05-06
  • 2011-08-20
  • 2021-04-20
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
相关资源
最近更新 更多