user3928094
user3928094

Reputation: 107

Correct way to chain two promises when the second promise depends on the first?

How do I make chain two JQuery async calls using JS Promises while avoiding the pyramid of doom? I know that I can convert a "JQuery" promise to a real promise like this:

Promise.resolve($.getJSON(url, params));

If I just want to wait for one promise, I can do this:

Promise.resolve($.getJSON(url1, params1))
.then(function(result){
  // do stuff
});

If I want to wait for two different ajax calls to be done, I can do this:

Promise.all(
[
  Promise.resolve($.getJSON(url1, params1)),
  Promise.resolve($.getJSON(url2, params2))
]).then(function(results_array){
  // do stuff
});

However, if I want one call to come after the other one, this doesn't work:

Promise.resolve($.getJSON(url1, params1))
.then(function(result){
  //do stuff
  return Promise.resolve($.getJSON(url2, params2));
}).then(function(result){
  //result is a promise, not the results from the second call to getJSON()...
  //and it doesn't even wait for the second call to finish.
  //result.then() is just going to bring me further into the pyramid of doom :(
});

Somehow, I want to call .then() on the promise constructed in the "do stuff" function. What's the idiomatic way to do this?

Upvotes: 1

Views: 2214

Answers (1)

Joseph
Joseph

Reputation: 119827

return Promise.resolve($.getJSON(url2, params2));

What you did was create an already resolved promise (via Promise.resolve) promise whose resolved value is the result of $.get(), which is also a promise. This is why "it doesn't even wait for the second call to finish" and "the result is a promise".

Also, you don't need to wrap the jQuery AJAX calls as they return promises. jQuery's promises act almost (but not entirely) the same as native promises.

Do this instead:

$.getJSON(url1, params1).then(function(result)){
  return $.getJSON(url2, params2);
}).then(function(result)){
  //result 2
});

Additionally, you're using jQuery. jQuery AJAX with promises can be done like this:

$.getJSON(url1, params1).then(function(result){
  // do stuff
});

Listening to multiple promises can be done this way in jQuery:

$.when($.getJSON(...), $.getJSON(...)).then(function(res1, res2){
  // do stuff
});

Upvotes: 3

Related Questions