2011-09-17 43 views
0
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模块node.js顺便提一下什么是异步任务的变量范围?

+0

喜欢你使用'async.queue'错误听起来沉重简化代码。 – Raynos

回答

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); 
    }); 
}); 
+0

不错!虽然我不是很想指定前面的任务。这似乎有点限制。在这种情况下显然不是问题,但通常我宁愿有办法在事实之后向cb对象添加任务。支持后? – broofa

+0

@broofa nope。在静态数量的请求之后运行之后。这个想法是,想要等待N个未确定的N个任务是不好的设计。我从来没有需要等待N个任务,我不知道N.通过一切手段给我一个例子,我会重构它以后使用 – Raynos

+0

在先前的问题,他问到可能试图批量1k数据库操作我建议异步。他也可以使用async.whilst和async.until。如果任务可以并发运行,则async.queue非常有用。我认为更大的问题是为什么他试图对Node进行如此多的操作。 –

1

问题不是变量作用域,而是async.queue不知道你正在调度的所有异步函数。具体来说,它不知道item.save()调用 - 它只知道计划 item.save()的外部函数。实际的保存和结果回调调用是在调用drain()之后异步完成的,这就是为什么itemIds显示为空。 (有道理?)

为了解决这个问题,我建议你使用Step module而不是async。具体来说,请看Step的group()功能,该功能允许您指出何时嵌套的异步控制流程已完成。