Let's take the following piece of code:
$.ajax({
type: 'POST',
dataType: dataType,
url: 'someUrl',
success: function(result){
$.ajax({
type: 'POST',
dataType: dataType,
url: 'anotherUrl',
data: queryToSearch,
success: function(anotherResult){
(do something that uses the first one result)
},
error: MyObj.defaultAjaxError
});
},
error: MyObj.defaultAjaxError
});
Can this be considered a bad practice? Does it have any hit on performance? If yes, is there a better way to do something like this?
Let's take the following piece of code:
$.ajax({
type: 'POST',
dataType: dataType,
url: 'someUrl',
success: function(result){
$.ajax({
type: 'POST',
dataType: dataType,
url: 'anotherUrl',
data: queryToSearch,
success: function(anotherResult){
(do something that uses the first one result)
},
error: MyObj.defaultAjaxError
});
},
error: MyObj.defaultAjaxError
});
Can this be considered a bad practice? Does it have any hit on performance? If yes, is there a better way to do something like this?
Share Improve this question asked Sep 4, 2013 at 20:30 Alexandre Wiechers VazAlexandre Wiechers Vaz 1,6173 gold badges19 silver badges21 bronze badges 6- Do both calls need to happen sequentially, or can they happen simultaneously? I don't see anything in the second AJAX call which depends on the first one. – David Commented Sep 4, 2013 at 20:31
-
i have been using this for a while and never had any issues ... i don't think there is other ways than
asyn:false
you can use to hold on ajax calls – Mina Gabriel Commented Sep 4, 2013 at 20:32 - Yes, @David, sorry for not being clear about that, i've edited the code :D – Alexandre Wiechers Vaz Commented Sep 4, 2013 at 20:33
- 3 There would be only two negative effects using nested method, you are creating maybe unneccessary closures, and adding more to callback spagetti. I suggest you use promises for that. Your code would be more readable at least. – Kemal Dağ Commented Sep 4, 2013 at 20:35
- This is the way to do it. – cssyphus Commented Sep 4, 2013 at 20:36
3 Answers
Reset to default 9Use Promises. Hopefully, Promises/A (as implemented in jQuery 1.8+ Deferred Objects), then:
$.ajax({..}) // Promise 1
.fail(function () {
// Oops! This will fire if (and only if) Promise 1 failed.
})
.then(function () {
// This will only fire if the first request had no error - was "done"
// We then return a NEW promise for the 2nd request. In a proper
// Promises/A, 'then' returns a (new) promise. (jQuery < 1.8 is broken.)
return $.ajax({..}) // Promise 2
})
// Note that these are for the 2nd promise which has been returned from
// the 'then' above OR from a 2nd promise created automatically by the default
// failHandler.
.fail(function () {
// Oops! This will fire if EITHER the promises (AJAX calls) fails.
// This happens because we are either binding to our Promise 2
// or to the auto-rejected promise returned from the default failHandler.
})
.done(function () {
// 2nd promise done - means both are done!
})
Using when
is not appropriate, because that would be "in parallel". (Actually, when
could be used with a "stub" promise that is wired to be accepted when the 2nd call pletes - however this doesn't benefit from then
chaining and it's not possible to meaningfully use the promise from the 2nd call directly for serial execution.)
One interesting thing to note is that fail
and done
are just shorthands for/restricted forms of then
. These methods can (and should) be used for clarity of intent/code.
If you need the callbacks to run sequentially, you need to do it this way. If they need to be done in parallel ( order is not guaranteed ), than you should not do it this way. It is not good or bad practice issue. It is a matter of what you need to acplish.
There is nothing explicitly wrong with doing it this way, but you may look into using jQuery Deferred Objects.