so i have to calculate some share in a loop. In every iteration of that loop i have to get a variable called rent from an array. So i devided the calculate function from the database stuff.
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++;
}
}
Now as you may see i am presented with the following trouble. Because I'm working in node.js, the only way to get the rent variable from the modules array is through this callback function called getRent(). The thing is, i need the share value after this step but outside of getRent().
Is there any way i can do this?
This is the getRent() - Function:
var getRent = function(modules, share, callback) {
// Searching for a fitting rent in the modules array
// Just assume this is happening here
callback(rent);
};
So the question is: How can i "return" share:
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
});
in any way?
If getRent is async there's no way to get the result synchronously. Fundamentally you don't know the value that getRent will end up supplying to its callback until it finally returns it. So it isn't a question of function scope, its a question of timing. You just have to wait for getRent to do its thing before you can get the value for rent. You need to refactor your code so that calculate is also async.
Something like:
// 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
});
The above answer is perhaps similar to how you might achieve it with vanilla JS. Using the async library like miggs suggests is probably a good idea in the long run. But like I said, if you use vanilla JS, or the async lib, there's no getting away from the fact that you'll have to refactor towards asynchronicity both in this code and the code that calls it.
You want to use the whilst method of the async library (npm install async) to simplify this:
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
}
);
If it was OK for you to request all 100 call in parallel, you could also use the parallel function.