2010-07-23 3 views
6

Ich verstehe, dass Javascript nicht mehrere Threads hat, aber ich würde gerne wissen, ob der folgende Code eine Chance hat zu brechen. Nach meinem Verständnis wird eine asynchrone Funktion, wie setTimeout oder ein AJAX-Aufruf nicht aufgerufen, sobald ein Codeabschnitt gestartet wird, kann er nicht angehalten werden, bis er abgeschlossen ist oder eine asynchrone Funktion aufruft.Gibt es eine Möglichkeit, dass zwei asynchrone Javascript-Funktionsinstanzen gleichzeitig zwei Codeblöcke ausführen?

Grundsätzlich wählen Benutzer mehrere Kontrollkästchen und dann eine Schaltfläche, die AJAX-Verarbeitung ihrer Auswahl ausführt. Mein Ziel ist es, ein "Speichern ..." -Symbol zu haben, das nur so lange bleibt, bis alle AJAX-Prozesse abgeschlossen sind und nach Abschluss eine Erfolgsmeldung angezeigt wird.

Abgesehen von allen AJAX-Fehlern, solange die Callback-Funktion in der jQuery.post in ihrer Gesamtheit ohne Unterbrechung ausgeführt wird, sehe ich nicht, wie die if(numProcessed == toProcess) jemals mehr als einmal oder weniger als einmal ausführen würde. Aber wenn zwei AJAX-Callbacks in die Callback-Funktion gelangen, erhöhen beide den numProcessed-Zähler, bevor sie entweder zu dem folgenden if gelangen, dann scheint es, dass der Code innerhalb von zwei Mal ausgeführt würde.

var numProcessed = 0; 
var checkedBoxes = jQuery("input[type=checkbox]:checked"); 
var toProcess = checkedBoxes.size(); 

checkedBoxes.each(function() { 
    jQuery.post('somepage.php',{...},function(results) { 
    numProcessed++; 
    if(numProcessed == toProcess) { 
     jQuery("#saving-message").remove(); 
     jQuery("#feedback-panel").text('Successfully processed all selections.'); 
    } 
    } 
} 
+0

Ich weiß nicht, Javascript oder Browser-Ausführung gut genug, um zu wissen, wie dies zu implementieren, aber wenn Sie die vollständige Kontrolle über die Umsetzung beider Teile des Codes, die lange/schwere Verarbeitung sind, Sie könnten zwei Objekte erstellen, die eine Funktion "Nächste verarbeiten" haben, eine interne Zählung innerhalb des Objekts beibehalten und eine Möglichkeit haben, zu signalisieren, dass die Verarbeitung abgeschlossen ist (eine andere Funktion oder ein "kompletter" boolescher Wert). Rufen Sie jeden von ihnen an, bis beide die Verarbeitung beendet haben. –

+0

@Merlyn: Ich hatte eine Verkettung in Erwägung gezogen, also beginnt nach dem Abschluss der nächste der nächste. Meine Bedenken waren, dass 1) es nicht so schnell sein würde, da zwischen jedem wir warten müssen, bis die HTML-Anfrage auf dem Server eintrifft, anstatt alle sofort aufzustehen. 2) Wenn etwas an einem Glied in der Kette versagt, werden alle verbleibenden nicht verarbeitet. 3) Abhängig von der Anzahl der Artikel, die möglicherweise den Stapel überfluten, da es verschachtelte Verschlüsse für jeden Artikel erstellen würde. Ich könnte mich irren, aber ich bin froh, dass ich mich stattdessen auf Javascripts Singlethreadness verlassen kann, anstatt eine komplexere Struktur zu erstellen. –

+0

@Merlyn: Ihren Kommentar, es scheint, als ob Sie eine bessere Struktur geplant hatten als ich in meinen Gedanken hatte. Ihre würden zulassen, dass # 2 und # 3 von meinem Kommentar ziemlich trivial gelöst werden, aber # 1 könnte immer noch ein Problem sein. –

Antwort

2

Es ist nur ein Thread in JavaScript so jede Funktion, die ausgeführt werden soll wird in Stapel gelegt und müssen warten, bis alle anderen auszuführen sind. In Ihrem Fall ist "each" die erste Funktion im Stack, also muss jede Callback-Funktion warten und wird in der Reihenfolge ausgeführt, in der sie auf den Stack gelegt wurde. Nach allem "numProcessed == toProcess" konnte nur einmal wahr sein.

+0

Sehr gut, froh, das zu hören. Ich denke, was verwirrend an der single-threaded Natur von Javascript ist, ist, dass es diese asynchronen Funktionen hat, die mich in einem größeren Sinn über Javascript als eine Art Multi-Threading denken lassen, da es einen Hintergrundprozess hat, der hereinfällt und Callback-Ausführungen auslöst in die Warteschlange, anstatt alles absolut prozedural/synchron zu sein. –

Verwandte Themen