【问题标题】:Node Stream: Not passing Callback Function a Value节点流:不向回调函数传递值
【发布时间】:2014-10-07 16:40:35
【问题描述】:

我正在研究 nodeschool.io 的 learnyounode http client exercise

这是任务:

编写一个程序,对提供的 URL 执行 HTTP GET 请求 你作为第一个命令行参数。写入字符串内容 从响应到控制台上的新行的每个“数据”事件 (标准输出)。

我的解决方案是:

var http = require("http");
var url = process.argv[2];


http.get(url, function(res){
  res.setEncoding('utf8');

    res.on('data', function(data){
        console.log(data);

    })
});

这很有效,但我很好奇建议的解决方案为什么有效。 console.log 和 console.error 如何使用 dataerror 对象。它们似乎没有传递给回调函数。

var http = require('http')

http.get(process.argv[2], function (response) {
  response.setEncoding('utf8')
  response.on('data', console.log)
  response.on('error', console.error)
})

【问题讨论】:

  • 在这两种情况下,您都传递了一个接收和打印文本的函数。在第一个中,它是一个匿名函数,调用console.log,在第二个中,它 console.log。两种方式,data 最终都会被传递给console.log

标签: javascript node.js callback


【解决方案1】:

通过使用response.on('data', console.log),您正在注册一个事件监听器,它将触发console.log() 函数作为它的回调。响应对象是一个事件发射器,当您的http.get 请求从远程服务器接收到数据时,它会发出 'data' 事件,该事件被侦听器拾取。该事件将接收到的数据作为第一个参数隐式传递给侦听器上的console.log 回调函数。 'error' 事件也是如此。

【讨论】:

    【解决方案2】:

    您的解决方案可以改写为:

    function logData (data) {
        console.log(data);
    }
    
    res.on('data', logData);
    

    由于您的 logData 函数只将数据传递给 console.log,因此您可以直接将 console.log 作为参数传递:

    res.on('data', console.log);
    

    请注意,传递数据的不是匿名函数的语法:

    res.on('data', function (data) {}); // <-- `data` is not passed
                                        //     due to this syntax
    

    相反,参数被传递是因为res.on 将数据作为第一个参数传递给传递给它的函数。来自stream.Readabledata 事件的文档(由http.incomingMessage 继承,即上面的res):

    事件:“数据”

    - chunk [Buffer|String] The chunk of data.
    

    如果你附加一个数据事件监听器,那么它会将流切换到流动模式,并且 > 数据将在可用时立即传递给你的处理程序。

    chunk 部分指定它是传递给传递给data 事件处理程序的函数的参数。


    请注意,console.log 不一定以允许您在其他 javascript 解释器中执行此操作的方式实现。例如,在 Chrome 和 Firefox 中,.log() 方法在内部依赖于this,因此如果您像这样简单地传递它,它将失败。相反,您需要将其绑定到 console:

    res.on('data', console.log.bind(console));
    

    或者像在您的解决方案中那样使用包装函数的更传统方式。碰巧 Node.js 没有这个问题。但是 Node 并不是唯一的服务器端 javascript 实现。因此,在将代码移植到其他解释器(例如 VertX)时要小心。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 2021-01-27
      • 1970-01-01
      相关资源
      最近更新 更多