0
function(obj){
for (property in obj) {
 if (obj.hasOwnProperty(property)) {
    // some code here
   if(condition){
    obj.children = example.getdata(base, obj.name);
     }
  // some more code releated to obj
   }
 }
if (obj.length == 10)
 {
  //some more function
 }
}

Now i want to make example.getdata async but i dont want to execute if statement that is after for loop until all the sync tasks are done. Its more of like i want all the example.getdata function calls to execute in parallel and after they finish work i execute if (obj.length).

I tried using promises and push all the promises and resolve them but i dont know how to handle the return value for each function call.

mughees ilyas
  • 506
  • 1
  • 9
  • 27
  • 1
    Can you show your setup with promises? This is a pretty common problem, easily solved with promises. – Evan Davis May 12 '15 at 15:54
  • What does exactly `example.getdata` do? AJAX request? – hindmost May 12 '15 at 15:56
  • Yes getdata is doing a rest call but it is also doing alot of other stuff so making the whole function async is my goal – mughees ilyas May 12 '15 at 16:00
  • @Mathletics it was along the lines of var promiseslist promiseslist.push(example.getdata(base, obj.name)); and then at bottom Promise.all(promiseslist).then(function () {}); but i dont know how obj.children will get its value for each call – mughees ilyas May 12 '15 at 16:08
  • 1
    Can you please show your complete code? Is `example.getData` supposed to be executed only once (or is the condition true on multiple iterations)? Why are you always overwriting `obj.children`? – Bergi May 12 '15 at 16:35
  • condition is true multiple times and oh lets just say its obj[properties].children. – mughees ilyas May 12 '15 at 18:04

3 Answers3

0

You can use Promise s.

Think of something like:

var jobs = get_jobs(data);
when_all(jobs).done(function (jobs_result) {
    console.log(jobs_result);
});

Where get_jobs returns a list or Promises and when_all will resolve when all it's input jobs are resolved.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
0

To run async tasks serially in a loop, you can't use a regular for loop because the for loop won't wait for your async operation to complete before executing the next cycle of the loop. Rather, you have to do your own custom iteration a slightly different way. Here's one way:

Assuming your getdata() function is actually asynchronous and has a completion function, you could structure things like this:

function myFunc(obj, callback) {
    var keys = Object.keys(obj);
    var cntr = 0;
    var results = [];
    function next() {
        if (cntr < keys.length) {
            example.getdata(obj[keys[cntr++]], function(result) {
                // do something with the result of each async operation here
                // and put it in the results array

                // kick off the next iteration
                next();
            });
        } else {
            // call the final callback because we are done now with all async operations
            callback(results);            
        }
    }
    // start the first iteration
    next();
}

If your getData function returns a promise or can be made to return a promise, then you can use promises for this too:

function myFunc(obj) {
    var keys = Object.keys(obj);
    keys.reduce(function(p, item) {
        return p.then(function(result) {
            // do something with the result of each async operation here
            // and put it in the results array

            return example.getdata(obj[item]);

        });
    }, Promise.resolve());
}

myFunc.then(function(results) {
    // all async operations done here, use the results argument
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

Here is a clean example of a for loop using promises. If you can pick a promise library libraries like Bluebird will make it even simpler:

function(obj){

  var props = Object.keys(obj), p = Promise.resolve();
  props.forEach(function(prop){
    p = p.then(function(){
      if(condition){ // can access obj[prop] and obj here
        obj.children = example.getData(...); // getData returns a promise
        return obj.children; // return the promise.
      }
    });
});

Promise.resolve(obj.children).then(function(children){
    // here the async call to get `.children` is done.
    // can wait for `p` too (the loop) if we care about it
    if(obj.length === 10) // do stuff
});
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504