Using jquery deferred to sync animation and ajax

ajax, deferred, fadein, jquery

Solution

When you use `$.when` (I know, funny sentence ;)), then the values with which the promises are resolved are passed as arguments to the callback functions. I.e. in your `done` callback, the first argument refers to the resolved value of `deferred1` and the second argument to `deferred2` (whatever that is).

Now, when an Ajax success callback is called, it gets passed three arguments:

- the response

- the status text

- the `jqXHR` object

You are only interested in the first.

So with this, your setup should be:

var promise1 = $.get(url);
var promise2 = $('#content').fadeTo(100, 0, 'linear').promise();

$.when(promise1, promise2).done(function(ajax_success) {
    $('#content').html(ajax_success[0]).fadeTo(400, 1, 'linear');
});

Also have a look at the `$.when` documentation.

Do I need `promise`?

No. It looks like `$.when` calls `.promise` internally when you pass a jQuery collection. But in other cases you would have to, so it makes sense to do this here as well, for consistency (thanks Alnitak).

And should i ... ? Should I ...? What would be ...?

There is no standard solution for this kind of problems. Promises are incredibly flexible and there are so many ways to use. I think they are not around long enough in JavaScript for standard patterns to emerge. Find/create something that makes sense to you and be consistent within your application.

The only thing I would recommend to do if you have multiple promises is put them in an array: jQuery $.when() with variable arguments.

Problem

I'm trying to get my head around the whole `deferred` concept and I'm trying to use it to synchronize a `fadeIn`/`fadeOut` animation together with an Ajax call. Basically I'm switching content on page doing: - Fetch content with ajax - On response FadeOut - Replace content - FadeIn However, If i understand `deferred`s right I might be able to do something like this: - fadeOut, and at the same time initialize Fetch content with ajax - When both the fadeOut and the Fetch content are complete: Change content - FadeIn Some code of the original solution: ``` $.get(url, function(page) { $('#content').fadeTo(100, 0, 'linear', function() { $(this).html(page.text).fadeTo(400, 1, 'linear'); }); } ``` I am trying to do something like this: ``` var deferred1 = $.get(url); var deferred2 = $('#content').fadeTo(100, 0, 'linear').promise(); $.when(deferred1, deferred2).done(function() { $('#content').html(page.text).fadeTo(400, 1, 'linear'); }); ``` I just can't really get clear on how to use it. And should i use done or then? Should I use pipe in a clever way? Do I need `promise`? What would be the more 'standardized' way to implement this?

Original source

Related problems