Ist die jQuery-Funktion "each ()" synchron?

131

Betrachten Sie dieses Szenario zur Validierung:

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

Mein Problem ist nun, dass der if- Block ausgeführt wird, bevor die Schleifen beendet sind. Ich habe erwartet, dass der Body von validateFormsynchron ausgeführt wird, aber es scheint, dass die jQuery- each()Funktion asynchron ausgeführt wird. Habe ich recht? Warum funktioniert das nicht?

Saeed Neamati
quelle
2
Wie sieht der Validierungscode aus? eachist synchron, aber der Code im Inneren ist möglicherweise nicht ...
einsamer
1
eachselbst wird synchron verarbeitet. Starten Sie eine eigene asynchrone Operation innerhalb der Schleife?
Jon
3
ähnliches Problem hier .. wie haben Sie es gelöst?
Sakthig
Es ist lange her, ich kann mich nicht erinnern. Aber ich weiß, dass mir die Antworten geholfen haben. Daher habe ich möglicherweise asynchrone Codeblöcke in meinem Validierungscode verwendet (z. B. den Versuch, die Adresse mithilfe einer Ajax-Anforderung zu validieren).
Saeed Neamati
1
hmm .. ich habe es auf diese Weise gelöst .. ich habe "return false" in jeder Funktion gemacht, was nicht funktioniert hat, denke ich .. jetzt behalte ich ein Flag in jeder Funktion und
gebe

Antworten:

157

Ja, die jQuery- eachMethode ist synchron. Fast ALLES JavaScript ist synchron. Die einzigen Ausnahmen sind AJAX, Timer ( setTimeoutund setInterval) und HTML5 Web Worker.
Ihr Problem liegt wahrscheinlich an einer anderen Stelle in Ihrem Code.

Abraham
quelle
7

jQueryist eine reine Javascript-Bibliothek. Außer ajax, setTimeoutund setIntervales gibt nichts, was asynchron ausgeführt werden kann JavaScript. Wird eachalso definitiv synchron ausgeführt. Es gibt definitiv einige js Fehler in dereach Blockcode. Sie sollten in der Konsole nach Fehlern suchen.

Alternativ können Sie sich die jQuery- Warteschlange ansehen , um eine beliebige Funktion in der Warteschlange auszuführen. Dadurch wird sichergestellt, dass die Funktion in der Warteschlange nur ausgeführt wird, wenn die vorherige Codeausführung abgeschlossen ist.

ShankarSangoli
quelle
7
Es gibt auch Versprechen ... nur zu sagen :)
6

Ein weiterer Grund für diese Frage wäre, dass .each die Iteration einfach stoppt, wenn die Funktion (.each ()) false zurückgibt, und eine zusätzliche Variable verwendet werden muss, um die Informationen "return false" zu übergeben.

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');
}
Morg.
quelle
2

Für mich funktioniert es asynchron. Wenn es synchron funktioniert, warum funktioniert es so:

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
});
Tuitx
quelle
2

return falseIn der .each()Funktion wird nur die Schleife unterbrochen, und der verbleibende Code außerhalb der Schleife wird weiterhin ausgeführt. Setzen Sie also ein Flag in der .each()Schleife und überprüfen Sie es außerhalb der Schleife.

M Hussain
quelle
1

Gleiches Problem. Also repariere ich so

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

}
user3027521
quelle
1

So mach ich es

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

Ich hatte das gleiche Problem. Mein $ .each befand sich innerhalb der Erfolgsfunktion von Ajax Call. Ich habe meinen Ajax-Aufruf durch Hinzufügen synchronisiert async: falseund es hat funktioniert.

Nilkamal Gotarne
quelle
-9

Die jQuery.each-Methode wird synchron wiederholt, Sie können jedoch nicht garantieren, dass die Elemente in einer bestimmten Reihenfolge durchlaufen werden.

Chris Pietschmann
quelle
21
Nein, es werden sie immer in der Reihenfolge durchlaufen, in der sie im Dokument erscheinen.
Abraham
3
Es hängt davon ab, worüber Sie iterieren. Jedes garantiert die Ausführung der Indexreihenfolge für ein Array, übernimmt jedoch keine Garantie für ein Objekt (was offensichtlich sein sollte).
Deadron