Reputation: 107
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
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