Joey Hipolito
Joey Hipolito

Reputation: 3166

Using deferred to chain loops with multiple ajax calls

There are multiple questions that already have an answer about this, but all aren't working so far it this kind of setup.

function login(u,p) {
   console.log(1);
   return $.post(url, {u,p});
}

function out() {
   console.log(3);
   //a function that does not return deferred
   // clear cookies
}

function doSomething() {
  console.log(2);
  // a function that returns a deferred
  return $.post(...);
}
var data = [{u: 'au', p: 'ap'}, {u: 'bu', p: 'bp'}]

$.each(data, function(k,v){
  login(v.u, v.p).then(doSomething).then(out);
});

I was expecting it's sequence to be like:

1
2
3
1
2
3

But I get

1
2
1
3
2
3

Why is it like that, even though I am waiting for the promise to be resolve using then

Upvotes: 3

Views: 1137

Answers (2)

Joey Hipolito
Joey Hipolito

Reputation: 3166

The idea is to create a recursive function like @Popnoodles have mentioned.

e.g.

function a() {
  return $.post();
}

function b() {
  return $.post();
}

function c() {
   console.log('no promise.');
}

// and the recursive main function

function main() {
   if(counter < data.length){
      $.when(a().then(b).then(c)).done(function(){
        counter++;
        main();
      });
   }
}

main();

Here is how it works, open the console to see how it logs the function in sequence.

Upvotes: 1

SomeKittens
SomeKittens

Reputation: 39522

If you want the logins to run synchronously:

var p = new jQuery.Deferred();
$.each(data, function(k,v){
  p.then(function() {
    return login(v.u, v.p);
  }).then(doSomething).then(out);
});

Each new item iterated over in $.each won't trigger a new response until p finishes the last one.

Upvotes: 2

Related Questions