Deferring on jQuery.each result

I am postponing deferrals and cannot figure out how / why this works:

<html>
<head>
</head>
<body>
    <div>
        1</div>
    <div>
        2</div>
    <div>
        3</div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>
        $("div").each(function (i) {
            $(this).delay(1000 * i).fadeOut();
        }).promise().done(function () { console.log("it done"); });
</script>
</body>
</html>

      

In prarticular: why can I name a promise after each one? Why is this technically possible? I have console.logged:

console.log($("div").each(function (i) {}));

      

and I can see the prom method in the prototype. But every function I do doesn't return any values, just:

$(this).delay(1000 * i).fadeOut();

      

So how does the promise relate to the animation result? (basically every iteration result)

EDIT 1: To be clear, perhaps I should have written my question like this:

How it's done is called after all animations have finished == how pain relief is interconnected with the animation that runs inside each callback function.

+3


source to share


2 answers


Have you tried adding a method promise()

inside a block? At the moment, you only execute it after the iteration is complete.

$("div").each(function (i) {
   $(this).delay(1000 * i).fadeOut().promise().done(function () { console.log("This individual animation is done."); });
}).promise().done(function () { console.log("Everything is done."); });

      


Your selector div

actually refers to quite a few elements on your page. Since it iterates through all of them, it performs a specific action on that element.



What you then do is asks jQuery to perform another action when all the previous actions associated with those elements have finished. According to their documentation, it returns an object:

when all actions of a particular type are associated with a collection, are in the queue, or have not finished.

So after everyone has fadeOut()

completed in the collection, it gets activated console.log()

.

+2


source


I've never seen it each

used with promises, but only animation

$('div') 
.animate({opacity: 0}, 1500) // animate all divs at once
.promise()
.done(function(){ 
   console.log('all done');
});

      

this will animate all divs at once and then execute a callback when all divs have finished animating. the problem with animations inside the loop is that it can't be coordinated and you won't be able to control when everything is done unless you use promises. If you really want to use each

then you need to create an array promises

and then usethen

 var promises = [];
 $('div').each(function(){
    var $this = $(this);
    promises.push($this.fadeOut('slow').promise());
 });

 $.when.apply($, promises).then(function(){
   console.log('all done');
 });

      



This is not the same as doing $('div').fadeOut('slow', function(){ alert('done'); });

, because the callback will be executed on the EACH element and the animated promises are a "task" with many subtasks

http://jsfiddle.net/LbHrQ/3/

The best use for promises is when you want to synchronize some of the asynchronous operations by their nature, like animations, ajax, things that use timeouts (in which case you need resolve()

to manually defer)

+4


source







All Articles