Invoking a jQuery function after .each() has completed

ID : 20206

viewed : 10

Tags : jqueryeachjquery

Top 5 Answer for Invoking a jQuery function after .each() has completed

vote vote

92

It's probably to late but i think this code work...

$blocks.each(function(i, elm) {  $(elm).fadeOut(200, function() {   $(elm).remove();  }); }).promise().done( function(){ alert("All was done"); } ); 
vote vote

87

An alternative to @tv's answer:

var elems = $(parentSelect).nextAll(), count = elems.length;  elems.each( function(i) {   $(this).fadeOut(200, function() {      $(this).remove();      if (!--count) doMyThing();   }); }); 

Note that .each() itself is synchronous — the statement that follows the call to .each() will be executed only after the .each() call is complete. However, asynchronous operations started in the .each() iteration will of course continue on in their own way. That's the issue here: the calls to fade the elements are timer-driven animations, and those continue at their own pace.

The solution above, therefore, keeps track of how many elements are being faded. Each call to .fadeOut() gets a completion callback. When the callback notices that it's counted through all of the original elements involved, some subsequent action can be taken with confidence that all of the fading has finished.

This is a four-year-old answer (at this point in 2014). A modern way to do this would probably involve using the Deferred/Promise mechanism, though the above is simple and should work just fine.

vote vote

75

Ok, this might be a little after the fact, but .promise() should also achieve what you're after.

Promise documentation

An example from a project i'm working on:

$( '.panel' )     .fadeOut( 'slow')     .promise()     .done( function() {         $( '#' + target_panel ).fadeIn( 'slow', function() {});     }); 

:)

vote vote

65

JavaScript runs synchronously, so whatever you place after each() will not run until each() is complete.

Consider the following test:

var count = 0; var array = [];  // populate an array with 1,000,000 entries for(var i = 0; i < 1000000; i++) {     array.push(i); }  // use each to iterate over the array, incrementing count each time $.each(array, function() {     count++ });  // the alert won't get called until the 'each' is done //      as evidenced by the value of count alert(count); 

When the alert is called, count will equal 1000000 because the alert won't run until each() is done.

vote vote

51

I found a lot of responses dealing with arrays but not with a json object. My solution was simply to iterate through the object once while incrementing a counter and then when iterating through the object to perform your code you can increment a second counter. Then you simply compare the two counters together and get your solution. I know it's a little clunky but I haven't found a more elegant solution so far. This is my example code:

var flag1 = flag2 = 0;  $.each( object, function ( i, v ) { flag1++; });  $.each( object, function ( ky, val ) {       /*         Your code here      */      flag2++; });  if(flag1 === flag2) {    your function to call at the end of the iteration } 

Like I said, it's not the most elegant, but it works and it works well and I haven't found a better solution just yet.

Cheers, JP

Top 3 video Explaining Invoking a jQuery function after .each() has completed

Related QUESTION?