Функция jQuery "each()" синхронна?

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

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() выполняется асинхронно. Я прав? Почему это не работает?

Ответ 1

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

Ответ 2

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

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

Ответ 3

Еще одна причина, по которой задавать этот вопрос, будет:.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');
}

Ответ 4

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

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

}

Ответ 5

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

 function getAllEventsIndexFromId(id) {
    var a;
    $.each(allEvents, function(i, val) {
        if (val.id == id) { a=i; }
    });
    return a;
 }

Ответ 6

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

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

Ответ 7

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

Ответ 8

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