learnyounode – 杂耍asynchronous – 为什么我的解决scheme不工作

有人可以解释为什么以下不能解决learnyounode研讨会中的“杂乱asynchronous”课程?

仅供参考如果有帮助,我已经将我的login页面留下了。 我正在努力看到我的解决scheme和我在网上find的答案之间的任何根本区别: https : //github.com/olizilla/nodeschooling/blob/master/learnyounode-answers/09-juggling-async.js

提前致谢!

var urlList = process.argv.slice(2, process.argv.length); //console.log(urlList); var urlResponseList = {}; for(var i=0; i < urlList.length; i++) { urlResponseList[urlList[i]] = ''; } var http = require('http'); console.log(urlList); for(var i = 0; i < urlList.length; i++) { //console.log(i); var url = urlList[i]; console.log("1 " + url); http.get(url, function (response) { console.log("2 " + url); console.log("3 " + i); response.setEncoding('utf8'); response.on('data', function (data) { urlResponseList[url] = urlResponseList[url] + data; }); response.on('end', function () { //console.log(stringResponse); //console.log(url); }); }); } console.log(urlResponseList); for(var i=0; i < urlList.length; i++){ console.log(urlResponseList[urlList[i]]); } 

我也有一个关于我在网上发现的解决scheme的问题: https : //github.com/olizilla/nodeschooling/blob/master/learnyounode-answers/09-juggling-async.js

 urls.forEach(function (item, index) { http.get(item, function (req) { req.setEncoding('utf8') req.pipe(concat(function (res) { data[index] = res; responseCount++ if (responseCount === urls.length) { console.log(data.join('\n')); } })) }) 

如果http.get是asynchronous的,并且可以在http.getcallback中信任“index”variables,即使它被设置在callback之外(在foreach循环中)?

我只是想发布下面更新的解决scheme。 感谢所有的帮助。 我的问题是我没有完全理解闭包是如何工作的。

 var urlList = process.argv.slice(2, process.argv.length); //console.log(urlList); var urlResponseList = []; for(var i=0; i < urlList.length; i++) { urlResponseList.push(''); } var http = require('http'); var responseCount = 0; //console.log(urlList); urlList.forEach(function(item, index){ //console.log(i); var url = urlList[index]; //console.log("1 " + url); http.get(item, function (response) { //console.log("2 " + url); //console.log("3 " + i); response.setEncoding('utf8'); response.on('data', function (data) { urlResponseList[index] = urlResponseList[index] + data; }); response.on('end', function () { responseCount++; if(responseCount == urlList.length) { //console.log("help"); console.log(urlResponseList.join('\n')); } }); }); }); //console.log(urlResponseList); 

http.get()在callback中asynchronous地返回它的结果(比如稍后)。 您的代码执行不会等待那个结果 – 即使响应尚未在这里,代码的其余部分也会继续运行。

因此,所有的请求将从你的第一个for循环立即发送,然后你的第二个循环将运行,然后稍后,响应将到达,callback将被调用。 您的响应将会asynchronous,因此在第一个for循环结束时将不可用。 所以,你的第一个console.log(urlResponseList); 将是空的,第二个for循环将无所事事。

asynchronous响应必须在交付的callback中进行处理,或者必须将其存储在某个地方,直到最后一个响应完成,然后可以处理所有的响应。

如果您不理解asynchronous响应背后的问题,请阅读以下两个参考:

如何返回来自asynchronous调用的响应?

为什么我的variables在函数内部修改后没有改变? – asynchronous代码引用


在callback之前声明的局部variables也会有问题,在callback被调用之前这些variables已经改变了。

下面是一个如何解决for循环问题的例子:循环中的JavaScript闭包 – 一个简单的实例