我正在尝试解决learnyounode的杂耍异步问题。
以下是我的尝试。但我没有得到理想的输出。我可以通过在谷歌搜索找到解决方案。但我想要的是学习节点基础知识。有人可以指导我出错的地方吗?
var http = require('http');
var bl = require('bl');
var output = [];
var cnt = 0;
for (var i in process.argv) {
if (i > 1 ) {
http.get(process.argv[i],function(response){
response.pipe(bl(function(err,data){
output[cnt] = data.toString();
cnt++;
if (output.length === (process.argv.length - 2)) {
printResult(output);
}
}));
});
}
}
function printResult(output){
for (var i = 0; i < output.length; i++) {
console.log(output[i]);
}
}
我得到的输出:
- ACTUAL:“shazza给我们带来了一些开膛手的那些砖砌的东西。来一条带着小辫子的小辫子。你这个小小的开膛手 腐烂的伴侣可以得到一些larrikin。 “
预料到:“shazza给我们带来了一些开膛手的那块砖头。带着一条小辫子,小心翼翼地注意着那个小小的开膛手。你的小开膛手 腐烂的伴侣可以得到一些larrikin。 “
ACTUAL:“当她是正确的澳大利亚规则时,请注意空中乒乓球。他没有一个战斗伙伴让投掷战斗机。 “
预计:“像野蛮一样建造起来就像一个笨蛋一样引人注目。像我的公主一样,把我的公寓弄得像个傻瓜一样。 mokkies没有担心shazza让我们有些摇摇欲坠。 “
实际:“像野蛮一样建造,不用担心会像一个笨蛋一样突出。像我的公主一样,把我的公寓弄出来。 mokkies没有担心shazza让我们有些摇摇欲坠。 “
预期:“当她正确地说澳大利亚规则时,请注意空中乒乓球。他没有一个战斗伙伴让投掷战斗机。 “
ACTUAL:“”
- 预期:“”
醇>
答案 0 :(得分:2)
如果我没有正确记住问题,您必须按照命令行参数中提供的URL的顺序打印响应。
您的解决方案的问题在于您实际上并未以正确的顺序存储您的回复 这部分代码:
// ...
output[cnt] = data.toString();
cnt++;
// ....
您异步触发了三个http
请求,并使用计数器output
将响应保存在cnt
数组中。由于响应可以按任何顺序到达,因此无法保证响应将以与触发请求相同的顺序保存。例如,如果请求第3个响应首先出现,它将存储在0
数组中的索引output
,这不是您想要的。
解决此问题而不是使用独立计数器。使用用于触发http请求的现有变量i
。因此,对于请求1,响应将保存在索引0处,因为请求2响应将保存在索引1处,依此类推。
在单独的函数中写下http get请求并传递索引i
并使用此索引i
保存您的回复。
//....
for (var i in process.argv) {
if (i > 1) {
httpGet(i);
}
}
function httpGet(index) {
http.get(process.argv[index], function(response) {
response.pipe(bl(function(err, data) {
output[index - 2] = data.toString();
cnt++;
// Use cnt to decide if all the responses have arrived and then print
if (cnt === (process.argv.length - 2)) {
printResult(output);
}
}));
});
}
// .....
http get请求需要包装在一个单独的函数中,否则,响应块的匿名函数内的变量i
的值对于每个函数都是相同的(在这种情况下将是4
) 。这是典型的封闭问题。我建议你阅读这些内容以获得详细解释:
JavaScript closure inside loops – simple practical example
Creating closures in loops: A common mistake
如果这对您有用,请告诉我。