Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery promise in function with each()

I'm tryin to call a own function and wait until its finishes. After the transitions end I want to start the next function. please have a look in my jsfiddle http://jsfiddle.net/hrm6w/

The console.log("upper finished") should start after console.log("promise finished") and all animations have ended.

And after all animations in the each-Object have ended I want to start the next actions(functions).

I think the promise()-function is all I need, but I just doesn't get this working.

Any help would be appreciated.

like image 842
felixaburg Avatar asked Jun 13 '12 00:06

felixaburg


People also ask

What is Promise () method?

It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

Does JQuery support promise?

The . promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. By default, type is "fx" , which means the returned Promise is resolved when all animations of the selected elements have completed.

How use JQuery Deferred and promise?

promise() will attach the methods onto it and then return this object rather than create a new one. This can be useful to attach the Promise behavior to an object that already exists. If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point.

Does JQuery return Ajax promise?

JQuery does all that and calls success callback if call succeed or error callback if it fails. Jquery also support promise out of box. $. ajax returns a promise object, so that we don't have to pass a callback function.


2 Answers

After playing a bit it seems you need to return the promise from the transition. I modified it a bit but has the same result.

This article helped explain some of the concepts: http://hermanradtke.com/2011/05/12/managing-multiple-jquery-promises.html

Demo: http://jsfiddle.net/lucuma/hrm6w/5/

    (function($) {
    //Transition Out
    $.fn.ajaxTransitionOut = function() {

        var $animators = $('.animate', this);
        $animators.each(function() {
            $(this).animate({
            left: 1000,
            opacity: 0
        }, 400);
        console.log('animating');
                        });
        return $animators.promise().done(function() {
            console.log('promise finished');
        });

    };

})(jQuery);

$(document).ready(function() {
    console.log('starting');
    $.when($('#content').ajaxTransitionOut()).done(function() {
        console.log('upper finished');
    });
    console.log('ending');

});​
like image 63
lucuma Avatar answered Oct 02 '22 01:10

lucuma


I think it's as simple as this :

(function($) {
    $.fn.ajaxTransitionOut = function() {
        return this.find('.animate').each(function() {
            $(this).animate({
                left: 500,
                opacity: 0
            }, 4000);
        });
    };
})(jQuery);
$.when($('#content').ajaxTransitionOut()).done(function() {
    $('html').css('backgroundColor','#999');
});

Fiddle - http://jsfiddle.net/hrm6w/8/

You will see I changed the constants and the terminal action to better observe the process.

I confess I don't fully understand why this works but it appears that a composite promise for all selected elements is implicit in the jQuery object returned by the plugin (and thus made available to .done() down the method chain).

I expect this only works because we are dealing with animations and a promise's default type is 'fx' (see documentation for .promise()).

Edit:

You can alternatively drop .when() and generate an explicit promise with .promise() in the method chain like this :

$('#content').ajaxTransitionOut().promise().done(function() {
    $('html').css('backgroundColor','#999');
});

The plugin remains the same.

like image 36
Beetroot-Beetroot Avatar answered Oct 02 '22 00:10

Beetroot-Beetroot