最近碰到的一个问题如下(代码仅为示意):
var rcds = [
'col_1',
'col_2',
'col_3',
'col_4',
'col_5',
'col_6',
'col_7',
]
var tasks = [];
for (var i = 0; i < rcds.length; i++) {
var rcd = rcds[i]
tasks.push(function(callback) {
request('http://localhost:8080', function(err, response, body) {
console.log(rcd);
callback(null);
});
});
}
async.parallel(tasks, function(err) {
if (err) {
throw err;
}
});
本来执行的结果应该是输出col_1 ~ col_7,但是看结果的时候发现输出了7个col_7。琢磨了下估计是变量rcd在异步执行的时候被赋值了,在SO上看到了这个回答,根据里面提到的东西把那段循环改成这样就行了:
for (var i = 0; i < rcds.length; i++) {
var rcd = rcds[i]
tasks.push(function(callback) {
var rcd = this.rcd;
request('http://localhost:8080', function(err, response, body) {
console.log(rcd);
callback(null);
});
}.bind({rcd: rcd}));
}
其中使用了bind把外部变量rcd的值绑定到了回调函数中,再调用的时候就不会变了。大概好像是和closures有关,还没弄懂,回头看。
另外,尝试重现这玩意的时候发现另一种解决办法,就是使用forEach:
rcds.forEach(function(rcd) {
tasks.push(function(callback) {
request('http://localhost:8080', function(err, response, body) {
console.log(rcd);
callback(null);
});
});
});
具体原因待查~