为什么要计算回调
Why count callbacks?
我正在学习learnyounode教程中的问题10:ASYNC JUGGLING。
此问题与中前面的问题(HTTP COLLECT)相同您需要使用http.get()。然而,这一次你会的提供三个url作为前三个命令行参数。
您必须收集由每个url并将其打印到控制台(标准输出)。你不需要打印出来长度,只是作为字符串的数据;每个URL一行。问题是您必须以与url相同的顺序打印它们作为命令行参数提供给您。
官方的解决方案包括计算回调:
var http = require('http')
var bl = require('bl')
var results = []
var count = 0
function printResults () {
for (var i = 0; i < 3; i++)
console.log(results[i])
}
function httpGet (index) {
http.get(process.argv[2 + index], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
results[index] = data.toString()
count++
if (count == 3) // yay! we are the last one!
printResults()
}))
})
}
for (var i = 0; i < 3; i++)
httpGet(i)
程序必须等到接收到所有三个响应后再打印出来,以便它们以输入的顺序输出。
我的尝试包括使用回调来确保正确的顺序:
var http = require('http')
var bl = require('bl')
var results = []
function printResults () {
console.log(results[0])
console.log(results[1])
console.log(results[2])
}
function httpGet (i) {
http.get(process.argv[2 + i], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
results[index] = data.toString()
}))
})
}
function httpGetAll (callback) {
httpGet(0)
httpGet(1)
httpGet(2)
callback()
}
httpGetAll(printResults)
但是这三次吐出undefined
。所以看起来好像printResults()
是在执行httpGet()
之前被调用的。看来我不像我想的那么懂回调。
所以我的问题是,是否有任何方法来实现这使用回调httpGetAll()
?或者我有计数回调到httpGet()
?
但是这个吐出三次undefined。因此,似乎printResults()是在执行三行httpGet()之前调用的。似乎我不像我想象的那样理解回调。
是的,你误解了异步代码的行为。三个httpGet()
首先被执行,但是它们的异步回调直到后面的事件循环开始时才执行。如果你看一下httpGet
,缩进1级的代码在第一个tick上运行,这只是真正的第一行,所有嵌套回调函数中缩进2级的代码都不会在同一个tick上执行。该代码只是在HTTP响应到达后安排在事件队列上,但node不只是等待,它在此期间继续运行。
所以我的问题是,是否有任何方法来实现这使用回调httpGetAll()?或者我必须计数回调到httpGet()?
是的,有一些方法可以正确地实现这一点,而不需要特别计算回调,但是,您必须以某种方式"跟踪"挂起的调用。计数是一种简单有效的方法,但是您也可以使用数组作为挂起调用的队列,在每个响应到达时从队列中删除一个元素,并且在队列为空时知道您已经完成了。您还可以使用启动false
的done
属性跟踪每个请求中的对象状态,并在响应到达时将其设置为true
,并通过确保所有done
属性都是true
来检查它们是否全部完成。从技术上讲,这不是计数,但它是一种类似性质的簿记。
- AngularJS:我可以跳过函数参数回调吗
- 要求未定义JS回调参数
- MeteorJS:在带有回调的vzaar api上正确使用wrapAsync
- 自引用回调
- 测试Angular Service解决错误回调中的promise
- 如何将一个JavaScript函数回调为多个函数
- JavaScript回调函数
- 用于回调的javascript参数
- 将json回调数据转换为日期
- 承诺在非节点式回调上使用Bluebird
- 如何在回调函数中执行流
- 使用reactjs setState回调获取上一个输入值的计算值
- 为什么这个带有对象调用函数的Javascript setInterval在传入回调时不计算内部参数
- Node.JS- R,Python大量计算识别回调何时返回并存储该结果
- 如何预先计算在waitForKeyElements()回调中使用的东西
- 为什么要计算回调
- 记录使用异步回调计算的总价值
- 计算节点/ JavaScript MySQL回调中的错误实例
- Express:如何计算路由回调
- 为什么在使用 jQuery.get() 的 ajax 调用的回调函数中计算 DOM 时为 null