我正在研究问题10:learnyounode教程中的ASYNC JUGGLING。
此问题与上一个问题(HTTP COLLECT)相同 你需要使用http.get()。但是,这次你会 提供了三个URL作为前三个命令行参数。
您必须收集每个提供给您的完整内容 URL并将其打印到控制台(stdout)。你不需要打印出来 长度,只是作为字符串的数据;每个网址一行。问题是 您必须按照与URL相同的顺序打印出来 作为命令行参数提供给你。
官方解决方案涉及计算回调:
$sql = "SELECT p.catid, p.catname, p.productid, p.prodimg,
GROUP_CONCAT(p.prodsize ORDER BY p.id ASC) as size,
GROUP_CONCAT(p.cost ORDER BY p.id ASC) as cost, p.prodname,
GROUP_CONCAT(c.prodsize,'-',c.quantity) as cart_details,
GROUP_CONCAT(DISTINCT(c.userid)) as user_id,
SUM(CASE WHEN c.status = 'add_to_cart' THEN quantity ELSE 0 END) AS quantity
FROM productsize p
LEFT JOIN cart c ON(c.productid = p.productid
AND p.prodsize = c.prodsize)
AND c.userid = {$userid}
WHERE p.catid = {$catid}
GROUP BY p.productid, c.status
ORDER BY p.productid ASC";
程序必须等到收到所有三个响应后再打印出来,这样它们才会按照输入的顺序出现。
我的尝试涉及使用回调来确保正确的顺序:
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()
的回调?
答案 0 :(得分:1)
但这三次吐出未定义。因此,似乎在执行三个httpGet()行之前调用了printResults()。好像我不理解回调以及我的想法。
是的,您误解了异步代码的行为方式。首先执行三个httpGet()
ARE,但是直到稍后的事件循环滴答时才会执行具有结果的异步回调。如果查看httpGet
,缩进1级的代码将在第一个刻度上运行,这实际上就是第一行,嵌套回调函数中缩进2级的所有代码都不会在同一个刻度上执行。该代码仅在事件队列上安排,以便稍后在HTTP响应到达之后,但节点不等待,它会继续进行过渡。
所以我的问题是,有没有办法在httpGetAll()上使用回调来实现这个目的?或者我是否必须将回调计入httpGet()?
是的,有一些方法可以正确实现这一点而无需专门计算回调,但是,您必须&#34;跟踪&#34;以某种方式挂起的电话。计数是一种简单有效的方法,但您也可以将数组用作待处理调用的队列,在每个响应到达时从队列中删除一个元素,并在队列为空时知道您已完成。您还可以使用done
属性跟踪每个请求的对象状态,该属性以false
开始,并在响应到达时设置为true
,并通过确保所有操作检查是否全部完成done
属性为true
。它在技术上并不重要,但它具有类似性质的簿记。