2013-02-14 69 views
0

所以我必須在循環中計算一些share。在該循環的每一次迭代中,我都必須從數組中獲取一個名爲rent的變量。所以我從數據庫中分離出calculate函數。現在Node.js中的函數範圍和回調函數

var calculate = function() { 
    while(count < 100) { 
     var share = 50; 
     var shareArray = []; 

     for(var i = 0; i < 100; i++) { 

      var pension = share*2; // mathematical stuff 
      // Gets a rent from a database and returns it in a callback 
      getRent(modules, share, function(rent) { 
       share = rent*foo; // some fancy mathematical stuff going on here 
       // I need to get the share variable above out of its function scope 
      }); 
        // I need the share variable right here 
      shareArray.push(share);  // the value of share will be for i = 0: 50, i= 1: 50 ... 
             // This is not what i want, i need the share value from getRent() 
     } 
     count++; 
    } 
} 

,你可以看到我的出現以下故障。因爲我在node.js中工作,所以從模塊數組獲取rent變量的唯一方法是通過稱爲getRent()的回調函數。事情是,我需要share這個步驟後,但getRent()以外的值。 有什麼辦法可以做到這一點?

這是getRent() - 功能:

var getRent = function(modules, share, callback) { 
     // Searching for a fitting rent in the modules array 
     // Just assume this is happening here 
     callback(rent); 
}; 

所以,問題是:以任何方式

getRent(modules, share, function(rent) { 
        share = rent*foo; // some fancy mathematical stuff going on here 
        // I need to get the share variable above out of its function scope 
}); 

:我怎麼能 「迴歸」 share

+0

「getFromDB()」是什麼樣的?我不明白這是如何工作的,因爲從數據庫中提取幾乎肯定涉及異步步驟。 – Pointy 2013-02-14 21:58:06

+0

如果你可以做一個**查詢來獲得你需要的所有值,而不是爲每個查詢單獨查詢,你幾乎肯定會更好,性能明智。一次只能做一件事會慢很多。 – Pointy 2013-02-14 21:59:22

+0

對不起。這只是一個構建的例子。真正的代碼將難以解釋這一點。假設這是有效的。嗯,我可以編輯它。 – 2013-02-14 21:59:48

回答

0

你想使用async庫(npm install async)的whilst方法來簡化這個:

var count = 0; 
var shareArray = []; 

async.whilst(
    function() { 
     return count < 100; 
    }, 
    function (next) { 
     count++; 
     getRent(function(rent) { 
      // What does modules do anyway?? 
      // Dont know where foo comes from... 
      shareArray.push(rent*foo); // some fancy mathematical stuff going on here 
      next(); 
     }); 
    }, 
    function (err) { 
     console.log(shareArray); 
     // Do sth. with shareArray 
    } 
); 

如果是OK你要求並行的所有100電話,你也可以使用parallel功能。

1

如果getRent是異步,則無法同步獲取結果。從根本上說,您不知道getRent最終會提供給它的回調的價值,直到它最終返回它爲止。所以這不是一個功能範圍的問題,它是一個時間問題。您只需等待getRent即可獲得rent的價值。您需要重構代碼,以便calculate也是異步的。

喜歡的東西:

// Refactor calculate to be async: 
function calculate(cb) { 
    var data = []; 
    for (var i=0; i<100; i++) { 
     getRent(function (rent) { 
      data.push(rent); 
      if (data.length === 100) cb(data); 
     }); 
    } 
} 

// And then use it async: 
calculate(function (data) { 
    // data array arrives here with 100 elements 
}); 

以上回答也許是類似於如何可能與香草JS實現它。從長遠來看,使用像miggs這樣的async庫可能是一個好主意。但正如我所說的,如果你使用vanilla JS或者async庫,那麼你就不得不重構這個代碼和調用它的代碼的異步性。