2013-02-14 71 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库,那么你就不得不重构这个代码和调用它的代码的异步性。