为什么要计算回调

Why count callbacks?

本文关键字:回调 计算 为什么      更新时间:2023-09-26

我正在学习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()?

是的,有一些方法可以正确地实现这一点,而不需要特别计算回调,但是,您必须以某种方式"跟踪"挂起的调用。计数是一种简单有效的方法,但是您也可以使用数组作为挂起调用的队列,在每个响应到达时从队列中删除一个元素,并且在队列为空时知道您已经完成了。您还可以使用启动falsedone属性跟踪每个请求中的对象状态,并在响应到达时将其设置为true,并通过确保所有done属性都是true来检查它们是否全部完成。从技术上讲,这不是计数,但它是一种类似性质的簿记。