learnyounode - 杂耍异步 - 为什么我的解决方案不起作用

时间:2014-10-14 04:11:54

标签: javascript node.js

有人可以解释为什么以下内容无法解决"杂乱的异步"在learnyounode研讨会上的课程?

仅供参考,如果有帮助,我已将原木线留在原处。我很难看到我的解决方案与我在网上找到的答案之间存在任何根本差异: 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]]);
}

我也对我在网上发布的解决方案有疑问: 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是异步的,可以&#34;索引&#34;变量在http.get回调中是否可信,即使它是在回调之外设置的(在foreach循环中)?

我只想在下面发布更新的解决方案。谢谢你的帮助。我的问题是我并没有完全理解闭包是如何工作的。

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);

1 个答案:

答案 0 :(得分:1)

http.get()在回调中异步(例如稍后)返回其结果。您的代码执行不会等待该结果 - 即使响应尚未在此处,其余代码仍会继续运行。

因此,所有请求将从您的第一个for循环中立即发送,然后您的第二个for循环将运行,然后稍后,响应将到达并且将调用回调。您的响应将以异步方式到达,因此在第一个for循环结束时将无法使用。因此,您的第一个console.log(urlResponseList);将为空,第二个for循环将无关。

异步响应必须在它们被传递的回调中处理,或者它们必须存储在某个地方,直到最后一个响应完成,然后可以在那时处理所有响应。

如果您不了解异步响应背后的问题,请阅读以下两个引用:

How do I return the response from an asynchronous call?

Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference


在调用回调之前,在回调之前声明的局部变量也存在问题。

以下是解决for循环问题的示例:JavaScript closure inside loops – simple practical example