В jQuery, это возможный вызвать обратный вызов или инициировать событие после вызова .each()
(или любой другой тип повторяющегося обратного вызова), завершился.
Например, я хотел бы, это "исчезает и удаляет" для завершения
$(parentSelect).nextAll().fadeOut(200, function() {
$(this).remove();
});
прежде, чем сделать некоторые вычисления и вставить новые элементы после $(parentSelect)
. Мои вычисления являются неправильными, если существующие элементы все еще видимы к jQuery и спящий/задерживающий, некоторое произвольное количество времени (200 для каждого элемента) походит на хрупкое решение в лучшем случае
Я могу легко .bind()
необходимая логика к обратному вызову события, но я не уверен, как чисто вызвать .trigger()
после того, как вышеупомянутое повторение завершилось. Очевидно, я не могу вызвать триггер в повторении, поскольку это стреляло бы многократно.
В случае $.each()
, Я рассмотрел добавление чего-то в конец аргумента данных (что я вручную искал бы в теле цикла), но я не хотел бы быть вынужденным, к, которому, таким образом, я надеялся, что был некоторый другой изящный способ управлять потоком относительно повторяющихся обратных вызовов.
Альтернатива ответу @tv:
var elems = $(parentSelect).nextAll(), count = elems.length;
elems.each( function(i) {
$(this).fadeOut(200, function() {
$(this).remove();
if (!--count) doMyThing();
});
});
Обратите внимание, что .each()
сам по себе является синхронным - оператор, следующий за вызовом .each()
, будет выполнен только после завершения вызова .each()
. Однако асинхронные операции, начатые в итерации .each()
, конечно же, продолжатся своим чередом. В этом и заключается проблема: вызовы для затухания элементов - это анимация, управляемая таймером, и она продолжается в своем собственном темпе.
Поэтому в приведенном выше решении отслеживается, сколько элементов затухает. Каждый вызов .fadeOut()
получает обратный вызов завершения. Когда обратный вызов замечает, что он подсчитал все задействованные исходные элементы, можно предпринять какое-либо последующее действие, будучи уверенным, что все затухание завершено.
Это ответ четырехлетней давности (на данный момент 2014 года). Современный способ сделать это, вероятно, включает использование механизма Deferred/Promise, хотя приведенный выше простой и должен работать просто отлично.
JavaScript выполняется синхронно, поэтому все, что вы поместите после each ()
, не будет выполняться до завершения each ()
.
Рассмотрим следующий тест:
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);
Когда вызывается предупреждение, счетчик будет равен 1000000, потому что предупреждение не будет запущено, пока не будет выполнено each ()
.
Если вы готовы сделать пару шагов, это может сработать. Однако это зависит от того, чтобы анимации завершались по порядку. Я не думаю, что это должно быть проблемой.
var elems = $(parentSelect).nextAll();
var lastID = elems.length - 1;
elems.each( function(i) {
$(this).fadeOut(200, function() {
$(this).remove();
if (i == lastID) {
doMyThing();
}
});
});
как насчет
$(parentSelect).nextAll().fadeOut(200, function() {
$(this).remove();
}).one(function(){
myfunction();
});