Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
509 views
in Technique[技术] by (71.8m points)

jquery - Continue Execution Only After .each() Completes

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...