Ответ 1
Да, метод jQuery each
является синхронным. Почти ВСЕ JavaScript является синхронным. Единственными исключениями являются AJAX, таймеры (setTimeout
и setInterval
) и веб-рабочие HTML5.
Ваша проблема, вероятно, где-то еще в вашем коде.
рассмотрите этот сценарий для проверки:
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()
выполняется асинхронно. Я прав? Почему это не работает?
Да, метод jQuery each
является синхронным. Почти ВСЕ JavaScript является синхронным. Единственными исключениями являются AJAX, таймеры (setTimeout
и setInterval
) и веб-рабочие HTML5.
Ваша проблема, вероятно, где-то еще в вашем коде.
jQuery
- это просто библиотека javascript. За исключением ajax
, setTimeout
и setInterval
ничего не может асинхронно выполняться в JavaScript
. Таким образом, each
определенно выполняется синхронно. В блочном коде each
есть определенная ошибка js. Вы должны заглянуть в консоль для каких-либо ошибок.
В качестве альтернативы вы можете посмотреть jQuery queue для выполнения любой функции в очереди. Это позволит убедиться, что функция в очереди будет выполняться только при завершении предыдущего выполнения кода.
Еще одна причина, по которой задавать этот вопрос, будет:.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');
}
Такая же проблема. Поэтому я исправляю это как
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;
}
}
}
Вот как я это делаю
function getAllEventsIndexFromId(id) {
var a;
$.each(allEvents, function(i, val) {
if (val.id == id) { a=i; }
});
return a;
}
Для меня это работает как асинхронный. Если он работает синхронно, почему он работает так:
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
});
Я была такая же проблема. мой $.each находился внутри функции успеха вызова ajax. Я сделал синхронный вызов ajax, добавив async: false
и он сработал.
Параметр jQuery.each синхронизирует, но вы не можете гарантировать, что он будет проходить через элементы в любом конкретном порядке.