我正在寻找一种只在.each()
完成执行后调用函数的方法。在下面的示例中,如何确保在 postPreparation()
完成后$('.element').each()
立即运行?
$('.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();
从技术上讲,我正在寻找一种方法来为.each()
调用回调函数。
注意:我刚刚在上面的示例中确认postPreparation()
仅在.each()
完成后才会执行。问题是我的prepareLayer()
使用AJAX构建新的HTML元素,因此each()
首先返回。正如@Alnitak所建议的那样,异步AJAX请求不会阻止.each()
过早返回。
答案 0 :(得分:9)
除非prepareLayer()
正在做异步(例如AJAX或动画),否则在prepareLayer()
完成之前,循环中的每次传递都无法终止,并且您的代码已经完成了您想要的任务。
FWIW,如果您现有的.each
循环中没有其他操作或参数,您实际上只需要写这个:
$('.element').each(prepareLayer);
即。不需要额外的匿名函数包装器。
另一方面,如果它正在执行异步操作,请使用延迟对象:
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);
答案 1 :(得分:0)
我会将对postPreperation
的调用包装成某种反对象。
例如:
function createEvent(numOfSignals, callback) {
var _event = {};
_event.signal = function() {
if(numOfSignals > 1) {
numOfSignals--;
}
else {
callback();
}
};
return _event;
}
var event = createEvent(numOfPreperations, postPreperation);
然后在prepareLayer
内,我会打电话给event.signal()
。如果numOfSignals
为1,则会立即调用postPreperation
。
你会想要改进这一点,但基本的想法应该有效。您可以查看该想法的示例here。
答案 2 :(得分:0)
使用jquery承诺:
$('.element').promise().done(function() {
postPreparation();
});