如何将变量的当前值发送到异步回调

时间:2014-03-26 03:45:44

标签: javascript node.js asynchronous node-mongodb-native

我遇到与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)

2 个答案:

答案 0 :(得分: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);
    };

答案 1 :(得分:0)

使用创建循环变量副本的技术,我发现我也能够使用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通常会传递引用而不是值not always