I have a web app which must call the server multiple times. So far, I had a long nested callback chain; but I would like to use jQuery's when
,then
etc. functionality. However, I can't seem to get stuff running again after using a then
.
$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
// This works fine
alert(args);
$('#content').replaceWith (args);
$('#progress-bar').progressbar ({value: 0});
})
.then ($.get('pages/test.html'))
.done (function(args)
{
// This prints the same as the last call
alert (args);
});
What am I doing wrong? I guess its some scoping issue, as I can see the second get
call being executed. Using two different args
variables does not help as the argument passed to the done function is still the first get
request.
I thought I would leave this little exercise here for anyone who may find it useful, we build an array of requests and when they are completed, we can fire a callback function:
The answer cdr gave, which has the highest vote at the moment, is not right.
When you have functions a, b, c each returns a $.Deferred() object, and chains the functions like the following:
Both b and c will run once the promise returned from a is resolved. Since both then() functions are tied to the promise of a, this works similiar to other Jquery chaining such as:
where both html() and css() function are called on the object returned from $('#id');
So to make a, b, c run after the promise returned from the previous function is resolved, you need to do this:
Here the call of function c is tied to the promise returned from function b.
You can test this using the following code:
Change the promise in function b() from resolve() to reject() and you will see the difference.
All three callbacks (the two with
then
and the one withdone
) are applied to the same request – the originalwhen
call. This is becausethen
returns the same Deferred object, rather than a new one, so that you can add multiple event handlers.You need to use
pipe
instead.Here is an wonderfully simple and highly effective AJAX chaining / queue plugin. It will execute you ajax methods in sequence one after each other.
It works by accepting an array of methods and then executing them in sequence. It wont execute the next method whilst waiting for a response.
As an update:
With modern jquery (1.8+) you don't need the preliminary when because get returns a Deferred Promise.
Also, pipe is deprecated. Use then instead. Just be sure to return the result of the new get which becomes the Promise attached to by subsequent then/*done*/fail calls.
So: