我有以下代码(dbclient
是Node.js的Redis客户端):
dbclient.zrange("cache", -1000000000000000, +1000000000000000, function(err, replies) {
logger.info("Replies: " + replies.length);
logger.info(err);
for (var i = 0; i < replies.length; i++) {
logger.info("I: " + i)
dbclient.hmget("doc:" + replies[i], "size", function(err, res) {
cache.set(replies[i], parseInt(res[0]));
logger.info(res[0]);
});
}
});
我注意到一种奇怪的行为:
第一个输出是:Replies: 195748
,但在for
循环中,我注意到它始终打印I: 195747
而res[0]
始终为198536
。这运行195747
次。
似乎它停留在最后一个索引上,并且不会遍历所有项目。
答案 0 :(得分:3)
这是Javascript中最常见的错误之一,
function(err,res){
cache.set(replies[i], parseInt(res[0]));
logger.info(res[0])
}
您正在使用i
,但这始终是父作用域中的一个。由于函数以异步方式作为回调运行,因此它始终是最后一次循环迭代的值。
将其更改为
(function(i) {
return function(err,res){
cache.set(replies[i], parseInt(res[0]));
logger.info(res[0])
};
})(i)
将i
绑定到最内层函数的范围
进一步说明:JavaScript closure inside loops – simple practical example