2013-05-12 65 views
2

好的,我認爲如果我複製整個node.js路由,以便看到我在說什麼,就會更容易。在NodeJS中存儲來自多個MongoDB查詢的數據

我想對我的MongoDB數據庫(每天一個)進行多個查詢。查詢運行良好,但是當他們觸發回調時,我的增量變量已經遞增。

因此,對於這個:

exports.graph = function(req, res) { 

    function pad(num, size) { 
    var s = num+""; 
    while (s.length < size) s = "0" + s; 
    return s; 
    } 

    database.collection('customerData', function(err, collection) { 

    for (var i = 2; i < 18; i++) { 

     sDay = pad(i, 2); 
     eDay = pad(i + 1, 2); 

     collection.find({ 
     DATE: { 
      $gte: sDay + 'APR13:00:00:00', 
      $lt: eDay + 'APR13:00:00:00' 
     } 
     }, function(err, cursor){ 
     cursor.toArray(function(err, data){ 
      var counter = 0; 
      for (var point in data) { 
      trans = parseInt(data[point].Total_Transaction * 100); 
      counter += trans; 
      } 

      console.log(i, counter/100); 
     }); 
     }); 
    } 
    }); 
} 

我得到這樣的輸出:

18 22023.29 
18 24483.03 
18 22644.11 
18 23194.31 
18 21560.99 
18 23024.32 
18 24384.93 
18 23138.34 
18 24400.63 
18 28418.6 
18 31691.65 
18 31111.62 
18 42358.74 
18 38355.76 
18 36787.52 
18 42870.19 
18 22023.29 
18 22644.11 
18 24483.03 
18 23194.31 
18 21560.99 
18 23024.32 
18 24400.63 
18 23138.34 
18 24384.93 
18 28418.6 
18 31691.65 
18 31111.62 
18 42358.74 
18 38355.76 
18 36787.52 
18 42870.19 

這個(顯然)不ideal-數字不一定回來的順序查詢被解僱,所以我很重要的是要弄清楚哪些地方在哪裏。

我找不出一種方法將我的算術結果以有意義的方式存儲在查詢回調中,以便稍後使用它。

有什麼想法?

回答

2

在附註中,與您的示例不同,以及下面的示例,您應該保存收集參考,而不是每次需要使用它時重新實例化。

至於你的問題,只是將每個調用的邏輯包裝在它自己的函數中。通過這種方式,您可以創建一個閉包,以記住每個特定查詢的用途。下面我創建了一個示例,將所有結果放入對象中,然後在所有查詢都完成後,按順序輸出所有結果。

var _outstanding = 0, 
    _results = {}; 

database.collection('customerData', function(err, collection) { 
    for (var i = 2; i < 18; i++) { 
    _outstanding++; 
    getDay(collection, i, getDayCallback); 
    } 
}); 

function getDay (collection, day, callback) { 
    sDay = pad(day, 2); 
    eDay = pad(day + 1, 2); 

    collection.find({ ...query obj... }).toArray(err, data) { 
    var counter = 0; 
    if (!err) { 
     for (var point in data) 
     counter += parseInt(data[point].Total_Transaction * 100); 
    } 

    callback(err, day, counter); 
    }); 
} 

function getDayCallback (err, day, count) { 
    // ...actually handle any errors, of course... 
    _results[day] = count; 

    if (--_outstanding === 0) { //display the results in-order when done 
    for (var i = 2; i < 18; i++) 
     console.log(i, _results[i]/100) 
    } 
} 

在這個人爲的例子,getDaygetDayCallback可以很容易地組合成一個功能,但你很可能要在現實世界他們分開。此外,不知道在哪裏218來自,但我猜他們不應該實際上被硬編碼多次像我一樣:)。

+0

這是完美的。謝謝! – 2013-05-12 06:03:21

1

@ Bret的回答是100%正確的。

我想貢獻一下,以顯示如何通過最小的修改來轉換代碼以包含閉包。由於閉包在這種情況下非常有用(常常會發生),如果可能有助於查看模式。

exports.graph = function(req, res) { 

    function pad(num, size) { 
     var s = num+""; 
     while (s.length < size) s = "0" + s; 
     return s; 
    } 

    database.collection('customerData', function(err, collection) { 

     for (var i = 2; i < 18; i++) { 

      sDay = pad(i, 2); 
      eDay = pad(i + 1, 2); 

      collection.find({ 
       DATE: { 
        $gte: sDay + 'APR13:00:00:00', 
        $lt: eDay + 'APR13:00:00:00' 
       } 
      }, (function(i){ //anonymous function which is sync-executed, bringing 
          // 'i' to closure-scope. 
       return function(err, cursor){ 
        cursor.toArray(function(err, data){ 
         var counter = 0; 
         for (var point in data) { 
          trans = parseInt(data[point].Total_Transaction * 100); 
          counter += trans; 
         } 

         console.log(i, counter/100); 
        }); 
       }); 
      }(i)) 
     } 
    }); 
} 
+0

這太棒了!現在對我有意義。謝謝! – 2013-05-13 18:08:05