Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continue Execution Only After .each() Completes

Tags:

jquery

I am looking for a way to call a function only after .each() finishes its execution. In the example below, how to make sure that postPreparation() runs immediately after $('.element').each() completes?

$('.element').each(function() {
  /** 
   * 'prepareLayer()' is a complex function that takes a while to complete and,
   *  as in this construct, needs to be invoked for each matched element. Basically,
   * 'prepareLayer()' adds a lot of new HTML elements to the page.
   */   
  prepareLayer();
});

/**
 * Ideally, this should immediately run _after_ the above function completes
 * i.e. after each '.element' finishes running prepareLayer().
 *
 * 'postPreparation()' needs to attach some event handlers for the new HTML elements
 * created in 'prepareLayer()'.
 */
postPreparation();

Technically, I am looking for a way to invoke a callback function for .each().

NOTE: I just confirmed, in the example above, that postPreparation() will execute only after .each() completes. The problem was my prepareLayer() builds the new HTML elements using AJAX, so each() returns prematurly. As suggested by @Alnitak, an asynchronous AJAX request wouldn't stop .each() from returning prematurely.

like image 727
moey Avatar asked Jan 17 '23 15:01

moey


1 Answers

Unless prepareLayer() is doing something asynchronous (e.g. AJAX, or animation) each pass around the loop can't terminate until prepareLayer() has finished anyway and your code will already do what you want.

FWIW, if there are no additional operations or parameters in your existing .each loop you actually just need to write this:

$('.element').each(prepareLayer);

i.e. there's no need for the additional anonymous function wrapper.

On the other hand, if it's doing something asynchronous, use deferred objects:

var def = [];
$('.element').each(function() {
    // have prepareLayer return a _promise_ to return
    def.push(prepareLayer());
});

function prepareLayer() {
    var jqxhr = $.get(..., function() {
        // do stuff with content
    });
    return jqxhr;
}

// use "when" to call "postPreparation" once every
// promise has been resolved
$.when.apply($, def).done(postPreparation);
like image 93
Alnitak Avatar answered Jan 29 '23 21:01

Alnitak