2011-09-10 14 views
111

considerano questo scenario per la convalida:La funzione jQuery "each()" è sincrona?

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

Ora, il mio problema è che, se il blocco ottenere eseguito prima cicli sono finiti. Mi aspettavo che il corpo di validateForm venisse eseguito in modo sincrono, ma sembra che la funzione jQuery each() venga eseguita in modo asincrono. Ho ragione? Perché questo non funziona?

+2

Che aspetto ha il codice di convalida? 'each' è sincrono, ma il codice interno potrebbe non essere ... – lonesomeday

+1

' each' stesso viene elaborato in modo sincrono. Stai iniziando qualche operazione asincrona da dentro il loop? – Jon

+3

problema simile qui .. come lo hai risolto? – sakthig

risposta

134

Sì, il metodo jQuery each è sincrono. Quasi TUTTO JavaScript è sincrono. Le uniche eccezioni sono AJAX, timer (setTimeout e setInterval) e Web worker HTML5.
Il tuo problema è probabilmente da qualche altra parte nel tuo codice.

-8

Il metodo jQuery.each esegue il ciclo in modo sincrono, ma non è possibile garantire che esegua il loop degli articoli in qualsiasi ordine specifico.

+18

No, le circolerà sempre nell'ordine in cui appaiono nel documento. – Abraham

+2

Dipende da cosa stai iterando. Ciascuno garantisce l'esecuzione dell'ordine dell'indice su un array ma non fornisce garanzie per un oggetto (che dovrebbe essere ovvio). – Deadron

6

jQuery è puramente una libreria javascript. Tranne ajax, setTimeout e setInterval non c'è nulla che possa essere eseguito in modo asincrono in JavaScript. Quindi each viene eseguito in modo sincrono. C'è sicuramente qualche errore js all'interno del codice di blocco each. Dovresti dare un'occhiata alla console per eventuali errori.

In alternativa è possibile dare un'occhiata a jQuery queue per eseguire qualsiasi funzione nella coda. Ciò assicurerà che la funzione in coda venga eseguita solo al termine dell'esecuzione del codice precedente.

+7

ci sono anche delle promesse ... solo dicendo :) – iwayneo

4

Un altro motivo per porre questa domanda sarebbe che .each interromperà semplicemente l'iterazione quando la funzione (.each()) restituisce false, e una variabile aggiuntiva deve essere utilizzata per passare le informazioni "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

Stesso problema. Così posso risolvere come questo

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

Ecco come lo faccio

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

Per me funziona come asincrono. Se funziona la sincronizzazione, perché funziona in questo modo:

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