Является ли функция jQuery «each ()» синхронной? - PullRequest
124 голосов
/ 10 сентября 2011

рассмотрите этот сценарий для проверки:

function validateForm (validCallback) {
   $('#first-name').add($('#last-name')).add($('#address')).each(function () {
      // validating fields and adding 'invalid' class to invalid fields.
   });
   // doing validation this way for almost 50 fields (loop over 50 fields)
   if ($('#holder .invalid').length == 0) {
       // submitting data here, only when all fields are validated.
   }
}

Теперь моя проблема в том, что блок if выполняется до завершения циклов. Я ожидал, что тело validateForm будет выполняться синхронно, но кажется, что функция jQuery each() выполняется асинхронно. Я прав? Почему это не работает?

Ответы [ 9 ]

148 голосов
/ 10 сентября 2011

Да, метод jQuery each является синхронным.Почти ВСЕ JavaScript являются синхронными.Единственными исключениями являются AJAX, таймеры (setTimeout и setInterval) и веб-работники HTML5.
Возможно, проблема в другом месте вашего кода.

7 голосов
/ 10 сентября 2011

jQuery - это чисто библиотека javascript.Кроме ajax, setTimeout и setInterval нет ничего, что может асинхронно выполняться в JavaScript.Так что each определенно выполняется синхронно.Определенно, есть некоторая ошибка js внутри блочного кода each.Вы должны посмотреть в консоли на наличие ошибок.

В качестве альтернативы вы можете взглянуть на jQuery queue , чтобы выполнить любую функцию в очереди.Это обеспечит выполнение функции из очереди только после завершения предыдущего выполнения кода.

4 голосов
/ 24 мая 2013

Другая причина задать этот вопрос заключается в том, что .each просто остановит итерацию, когда функция (.each ()) вернет false, и для передачи информации «return false» должна использоваться дополнительная переменная.

var all_ok=true;
$(selector).each(function(){
    if(!validate($(this))){
        all_ok=false; //this tells the outside world something went wrong
        return false; //this breaks the .each iterations, returning early
    }
});
if(!all_ok){
    alert('something went wrong');
}
1 голос
/ 11 апреля 2019
Функция

return false в .each() прерывает только цикл, а оставшийся код вне цикла все еще выполняется. Поэтому установите флаг в цикле .each() и проверьте его вне цикла.

1 голос
/ 25 августа 2016

Для меня это работает как асинхронный. Если это работает синхронизация, почему это работает так:

var newArray = [];
$.each( oldArray, function (index, value){
        if($.inArray(value["field"], field) === -1){
            newArray.push(value["field"]);
        }
    }
);

//do something with newArray here doesn't work, newArray is not full yet

$.when.apply($, newArray).then(function() {
    //do something with newArray works!! here is full
});
1 голос
/ 27 мая 2015

Вот как я это делаю

 function getAllEventsIndexFromId(id) {
    var a;
    $.each(allEvents, function(i, val) {
        if (val.id == id) { a=i; }
    });
    return a;
 }
1 голос
/ 26 сентября 2014

Та же проблема.Так что я исправляю вот так

var y = jQuery(this).find(".extra_fields");
for(var j in y)
{
    if( typeof  y[j] =='object')
    {
        var check = parseInt(jQuery(y[j]).val());
        if(check==0){
            jQuery(y[j]).addClass('js_warning');
            mes="Bạn vui lòng chọn đầy đủ các thuộc tính cho sản phẩm";
            done=false;
            eDialog.alert(mes);
            return false;
        }
    }

}
0 голосов
/ 18 августа 2018

У меня была такая же проблема. мой $ .each был внутри функции успеха вызова ajax. я сделал синхронный вызов AJAX, добавив async: false, и это сработало.

0 голосов
/ 10 сентября 2011

Метод jQuery.each зацикливается синхронно, но вы не можете гарантировать, что он будет циклически проходить по элементам в любом конкретном порядке.

...