2014-03-26 56 views
1

我有与this question相同的问题,但无法获得解决方案的工作。我正在尝试编写一个nodejs脚本,它将首先检查mongo中的缓存值,但如果它不存在,那么请关闭并计算它。问题是findOne()回调没有获得循环变量的原始值,因此回调函数无法正确计算和存储该值。 (我已经省略了实际的提取,存储和返回以专注于我所遇到的实际问题)。无论我做什么,我都无法获得原始价值以进入回调。如何将变量的当前值发送到异步回调

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) 

回答

3

我猜你的问题是,你要发送的值d到包装的函数,并且该函数内部修改以某种方式,价值。由于d是对循环迭代器的引用,因此修改它会修改循环。该解决方案是创建自己的函数中的对象的副本

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

哇的值!非常喜欢这个解决方案 – Sethunath

0

使用创建循环变量,我发现我也可以使用绑定()来得到相同的副本的技巧结果。同样的结果,但代码更好看我的眼睛。

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似乎通常经过一个参考,而不是虽然not always