Please see this code:
for(var k=0;k<pods.length;k++){
var currentQueryList = new Array();
currentQueryList[0]=pods[k].queryname;
console.log("Hello :"+i);
queryBuilderDWRService.getDataForAllPods(currentQueryList, {callback:function(map){
podsDataMap = map;
console.log("Hello"+k+":");
var pod = pods[k];
displayPod(k, pod, false);
}});
}
In this code, the for loop is completing before the call to queryBuilderDWRService.getDataForAllPods()
returns actual data, which I'm using to get data from a database.
It I try console.log("Hello"+i);
it is printing Hello :1, Hello :2, Hello :3, Helllo :4,
up to array length with no data from DB, meaning that the for loop is completing its execution before than queryBuilderDWRService.getDataForAllPods()
returns.
What I need is that, once control is entering in the for loop, it has to complete the execution of queryBuilderDWRService.getDataForAllPods() and only then the next iteration can follow.
Thanks in advance.
You can use "asynchronous pseudo-recursion" instead of a for
loop, with the general pattern that I use being:
var pods = [ ... ];
(function loop() {
if (pods.length) {
var pod = pods.shift(); // take (and remove) first element
// do something with "pod"
...
// recurse - put this inside a finish callback if "do something" is async
loop();
}
})(); // closing braces start invocation immediately
where in your case, the call to loop
should be the last thing inside your callback function.
NB: This pattern can also be used to avoid the "browser not responding" error seen with longer running non-async operations by replacing the call to loop()
with setTimeout(loop, 0)
.
This use of setTimeout
turns a synchronous recursive function into an asynchronous pseudo-recursive one, in the process avoiding the possibility of any stack overflow errors.
The only downside is the 4ms minimum delay between iterations.