Вызов функции jQuery после .each () завершился

В jQuery, это возможный вызвать обратный вызов или инициировать событие после вызова .each() (или любой другой тип повторяющегося обратного вызова), завершился.

Например, я хотел бы, это "исчезает и удаляет" для завершения

$(parentSelect).nextAll().fadeOut(200, function() {
    $(this).remove();
});

прежде, чем сделать некоторые вычисления и вставить новые элементы после $(parentSelect). Мои вычисления являются неправильными, если существующие элементы все еще видимы к jQuery и спящий/задерживающий, некоторое произвольное количество времени (200 для каждого элемента) походит на хрупкое решение в лучшем случае

Я могу легко .bind() необходимая логика к обратному вызову события, но я не уверен, как чисто вызвать .trigger() после того, как вышеупомянутое повторение завершилось. Очевидно, я не могу вызвать триггер в повторении, поскольку это стреляло бы многократно.

В случае $.each(), Я рассмотрел добавление чего-то в конец аргумента данных (что я вручную искал бы в теле цикла), но я не хотел бы быть вынужденным, к, которому, таким образом, я надеялся, что был некоторый другой изящный способ управлять потоком относительно повторяющихся обратных вызовов.

180
задан VK Da NINJA 12 June 2016 в 18:02
поделиться

4 ответа

Альтернатива ответу @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, хотя приведенный выше простой и должен работать просто отлично.

159
ответ дан 23 November 2019 в 06:11
поделиться

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 () .

23
ответ дан 23 November 2019 в 06:11
поделиться

Если вы готовы сделать пару шагов, это может сработать. Однако это зависит от того, чтобы анимации завершались по порядку. Я не думаю, что это должно быть проблемой.

var elems = $(parentSelect).nextAll();
var lastID = elems.length - 1;

elems.each( function(i) {
    $(this).fadeOut(200, function() { 
        $(this).remove(); 
        if (i == lastID) {
           doMyThing();
        }
    });
});
1
ответ дан 23 November 2019 в 06:11
поделиться

как насчет

$(parentSelect).nextAll().fadeOut(200, function() { 
    $(this).remove(); 
}).one(function(){
    myfunction();
}); 
0
ответ дан 23 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: