2014-03-26 59 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