如何发送variables的当前值到asynchronouscallback

我有这个问题相同的问题,但不能得到解决scheme的工作。 我正在尝试编写一个nodejs脚本,它将首先检查mongo中的caching值,但是如果它不存在,那么就closures并计算它。 问题是,findOne()callback没有得到循环variables的原始值,所以callback不能正确计算和存储的价值。 (我已经省略了实际的提取,存储和返回,以专注于我有的实际问题)。 无论我做什么,我都无法获得原始价值来回馈。

for (var d=start_date; d<now; d.setHours(d.getHours()+1)) { (function(key) { console.log('caller='+key) db.collection('avgs').findOne( { date: key.toISOString() },function (err,data) { console.log('callback='+key); if (data) { //return data } else { // compute average for given date , insert into database and return value } }); })(d); }; 

控制台日志显示了这一点

 caller=Tue Mar 25 2014 00:00:00 GMT+1030 (CST) caller=Tue Mar 25 2014 01:00:00 GMT+1030 (CST) caller=Tue Mar 25 2014 02:00:00 GMT+1030 (CST) caller=Tue Mar 25 2014 03:00:00 GMT+1030 (CST) callback=Wed Mar 26 2014 14:00:00 GMT+1030 (CST) callback=Wed Mar 26 2014 14:00:00 GMT+1030 (CST) callback=Wed Mar 26 2014 14:00:00 GMT+1030 (CST) callback=Wed Mar 26 2014 14:00:00 GMT+1030 (CST) 

我猜你的问题是,你发送的值d到包装函数,并在该函数内以某种方式修改该值。 由于d是对你的循环迭代器的引用,修改它会修改你的循环。 解决办法是在你的函数中创build一个对象的副本

  for (var d=start_date; d<now; d.setHours(d.getHours()+1)) { (function(_key) { // Make a copy of the object you passed in, so that modifying it // won't screw up your loop var key = new Date(_key); console.log('caller='+key) db.collection('avgs').findOne( { date: key.toISOString() },function (err,data) { console.log('callback='+key); if (data) { //return data } else { // compute average for given date , insert into database and return value } }); })(d); }; 

使用创build循环variables的副本的技术,我发现我也能够使用bind()来获得相同的结果。 同样的结果,但代码更好看我的眼睛。

 db.collection('avgs').findOne( { date: key.toISOString() },found.bind(this,new Date(d)); function found(key,err,data) { console.log('callback='+key); if (data) { //return data } else { // compute average for given date , insert into database and return }; 

看来,JavaScript通常传递一个引用,而不是一个值,虽然并不总是