2011-09-10 28 views
111

consideran este escenario para la validación:¿La función jQuery "each()" es síncrona?

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

Ahora, mi problema es que, si el bloque conseguir ejecutado antes de que se terminaron los bucles. Esperaba que el cuerpo de validateForm se ejecutara sincrónicamente, pero parece que la función jQuery each() se ejecuta de forma asíncrona. ¿Estoy en lo cierto? ¿Por qué esto no funciona?

+2

¿Cómo se ve el código de validación? 'each' es sincrónico, pero el código interno podría no ser ... – lonesomeday

+1

' each' se procesa de forma síncrona. ¿Estás iniciando alguna operación asíncrona propia dentro del ciclo? – Jon

+3

problema similar aquí ... ¿cómo lo resolvió? – sakthig

Respuesta

134

Sí, el método jQuery each es síncrono. Casi TODO JavaScript es sincrónico. Las únicas excepciones son AJAX, temporizadores (setTimeout y setInterval) y HTML5 Web Workers.
Tu problema probablemente sea otro en tu código.

-8

El método jQuery.each realiza un ciclo Sincrónicamente, pero no puede garantizar que recorrerá los elementos en un orden específico.

+18

No, siempre se repetirá en el orden en que aparecen en el documento. – Abraham

+2

Depende de lo que está iterando. Cada uno garantiza la ejecución de órdenes de índice en una matriz pero no ofrece garantías para un objeto (lo que debería ser obvio). – Deadron

6

jQuery es puramente una biblioteca javascript. Excepto ajax, setTimeout y setInterval, no hay nada que se pueda ejecutar asincrónicamente en JavaScript. Entonces, each definitivamente se ejecuta de forma síncrona. Definitivamente hay algunos errores js dentro del código de bloque each. Deberías echarle un vistazo a la consola para ver si hay algún error.

Como alternativa, puede echar un vistazo a jQuery queue para ejecutar cualquier función en la cola. Esto asegurará que la función en cola se ejecutará solo cuando se complete la ejecución del código anterior.

+7

también hay promesas ... solo digo :) – iwayneo

4

Otra razón para hacer esa pregunta sería que .each simplemente detendrá la iteración cuando la función (.each()) devuelva falso, y se debe usar una variable adicional para pasar la información "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'); 
} 
0

Mismo problema. Así puedo solucionar esta manera

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

} 
1

Así es como lo hago

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

Para mí funciona como asíncrona. Si funciona sincronizado, por qué funciona así:

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