异步任务的变量范围是什么?

时间:2011-09-17 05:55:27

标签: node.js asynchronous

var itemIds, result, taskQueue, _i, _len;
itemIds = [];
taskQueue = async.queue(function(task, callback) {
  console.log('Hello ' + task.name);
  return callback();
}, 10);
for (_i = 0, _len = results.length; _i < _len; _i++) {
  result = results[_i];
  taskQueue.push({}, function(err) {
    var item;
    item = new Item(result);
    return item.save(function(err, new_item) {
      itemIds[itemIds.length] = new_item._id;
      console.log(new_item._id);
      return console.log(itemIds);
    });
  });
}
taskQueue.drain = function() {
  console.log('Queue Done!');
  return console.log(itemIds.length);
};

是我的代码。但是当drain运行时,itemIds显示为空。顺便使用async模块{/ 1}}

2 个答案:

答案 0 :(得分:2)

我个人建议您使用after

大幅简化代码
var slice = Array.prototype.slice;

var cb = after(results.length, function() {
    var items = slice.call(arguments);
    console.log("All done");
    console.log(items.length);
});

results.forEach(function(result) {
    item = new Item(result);
    item.save(function(err, newItem) {
        cb(newItem);   
    }); 
});

答案 1 :(得分:1)

问题不在于变量范围,而是async.queue不知道您正在调度的所有异步函数。具体来说,它不知道item.save()调用 - 它只知道调度 item.save()的外部函数。在调用drain()之后,实际保存和生成的回调调用是异步完成的,这就是为什么itemIds显示为空的原因。 (有意义吗?)

要解决此问题,我建议您使用Step module代替async。具体来说,请查看Step的group()功能,该功能允许您指示何时完成此类嵌套异步控制流程。