Node.js中的函数范围和回调函数
问题描述:
所以我必须在循环中计算一些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
?
答
你想使用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
功能。
答
如果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
库,那么你就不得不重构这个代码和调用它的代码的异步性。
“getFromDB()”是什么样的?我不明白这是如何工作的,因为从数据库中提取几乎肯定涉及异步步骤。 – Pointy 2013-02-14 21:58:06
如果你可以做一个**查询来获得你需要的所有值,而不是为每个查询单独查询,你几乎肯定会更好,性能明智。一次只能做一件事会慢很多。 – Pointy 2013-02-14 21:59:22
对不起。这只是一个构建的例子。真正的代码将难以解释这一点。假设这是有效的。嗯,我可以编辑它。 – 2013-02-14 21:59:48