在for循环中管理node.js异步

时间:2014-12-12 15:59:01

标签: node.js mongodb asynchronous

全部,

问题定义:我需要协调几个输入。我们的想法是遍历主文件并利用async.waterfall来处理剩余的文件。我遇到的问题如下:

1)循环工作完美,我看到所有正确的记录过程 2)异步在循环完成之前不会处理,并反复处理最后一条记录。

控制台如下所示:

- 来自循环 - 记录1 - 来自循环 - 记录2 - 来自循环 - 记录3 - 来自循环 - 记录4 - 来自循环 - 记录5 - 来自循环 - 记录6 .............. - 来自循环 - 记录329

- 来自异步 - 记录329 - 来自异步 - 记录329 - 来自异步 - 记录329 - 来自异步 - 记录329 - 来自异步 - 记录329 .............. - 来自异步 - 记录329

代码如下所示:

MongoClient.connect("mongodb://localhost:27017/preInc", function(err, db) {
if(err) { return console.dir(err); }
var collection = db.collection('resource_Tbl');
collection.find().toArray(function(err, items)
    {
        if(err) {
            return console.dir(err); }
        else {
            test = items;
        }
        for (var i = 0; i < items.length; i++)
        {
            var temp = items[i]._id.toHexString();
            var name = items[i].name;
            console.dir(temp + "-|-" + name);
            Async.waterfall([
                    function getGeoAddress(callback)
                    {
                        console.dir(temp + "   " + name);
                        callback(null, 'unknown');
                    },
                ],
                function (err, results)
                {
                    if (err)
                    {
                        console.log(err);
                    }
                    else
                    {
                    }
                });
        }
        res.render('heatmap', { data: test, headerX:'preInc.org' });
    });
});

});

我正在继续努力,但......

提前谢谢你,

...罗杰

1 个答案:

答案 0 :(得分:0)

async模块实际上阻止流程。所有异步进程都放入事件循环中,只有主线程完成您的特定操作才能获取。因此,在您的情况下,您应该执行async.eachasync.eachSeries

之类的操作

您的问题类似于以下内容:

for(var i = 0; i < 10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

这将输出10次“9”,因为它仅在下一次迭代时执行,此时,i = 9

我不能100%确定您对以下声明的意思:

  

我们的想法是遍历主文件并利用async.waterfall来处理剩余的文件。

但实际上有两种解决方案:

如果您需要处理每个文件的结果,请使用async.each,如前所述。例如:

async.each(items, function(item, next) {}, function() {
 // Here all the files has been processed, can return to the requester via res.send() or res.render();
   res.render();
});

如果您需要使用结果,则可以在以后处理该操作。然后在这种情况下,您可以使用立即函数,如下所示:

for(var i = 0; i < items.length; i++) {
  // create and call an immediate function
  (function(i) {
    // now i would be 0..items.length-1 correctly. 
    async.waterfall([], function() {});
  } (i);
}

这将创建放入事件循环的事件,计划在以后调用,但具有正确的范围。