Wie Sie vielleicht wissen, ist die Ausführungsumgebung der JavaScript -Sprache "einzelner Thread".
Der sogenannte "einzelne Thread" bedeutet, dass eine Aufgabe jeweils nur abgeschlossen werden kann. Wenn es mehrere Aufgaben gibt, müssen Sie sich anstellen, die vorherige Aufgabe ausführen, die nächste Aufgabe ausführen und so weiter.
Der Vorteil dieses Modells besteht darin, dass es relativ einfach zu implementieren ist und die Ausführungsumgebung relativ einfach ist. Der Nachteil ist, dass die nachfolgenden Aufgaben, solange es eine Aufgabe gibt, die lange Zeit dauert, die Ausführung des gesamten Programms verzögert werden muss. Gemeinsame Browser reagieren häufig nicht (falscher Tod), da ein bestimmtes Stück JavaScript -Code für lange Zeit (wie z.
Um dieses Problem zu lösen, unterteilt die JavaScript -Sprache den Ausführungsmodus von Aufgaben in zwei Typen: synchron (synchron) und asynchron (asynchron).
"Synchronmodus" ist das Muster des vorherigen Abschnitts. Die letztere Aufgabe wartet darauf, dass die vorherige Aufgabe endet und dann ausgeführt wird. Die Ausführungsreihenfolge des Programms ist konsistent und synchron mit der Anordnung der Aufgaben. Der "asynchrone Modus" ist völlig anders. Jede Aufgabe hat eine oder mehrere Rückruffunktionen (Rückrufe). Nachdem die vorherige Aufgabe beendet ist, ist es nicht die nächste Aufgabe, sondern die Rückruffunktion wird ausgeführt. Die letztere Aufgabe wird ausgeführt, ohne auf die vorherige Aufgabe zu warten, sodass die Ausführungsreihenfolge des Programms inkonsistent und asynchron mit der Anordnungsreihenfolge der Aufgaben ist.
"Async -Modus" ist sehr wichtig. Auf der Browserseite sollten langfristige Operationen asynchron ausgeführt werden, um zu vermeiden, dass der Browser die Reaktion verliert. Das beste Beispiel sind Ajax -Operationen. Auf der Serverseite ist der "Asynchronous-Modus" sogar der einzige Modus, da die Ausführungsumgebung einsthread ist. Wenn alle HTTP-Anforderungen synchron ausgeführt werden dürfen, sinkt die Serverleistung stark und verliert bald ihre Antwort.
Dieser Artikel fasst 4 Methoden der "Asynchronous -Modus" -Programmierung zusammen. Mit dem Verständnis können Sie JavaScript -Programme mit angemessenerer Struktur, besserer Leistung und bequemerer Wartung schreiben.
1. Rückruffunktion
Dies ist die grundlegendste Methode der asynchronen Programmierung.
Angenommen, es gibt zwei Funktionen F1 und F2, wobei letztere auf das Ausführungsergebnis des ersteren warten.
Die Codekopie lautet wie folgt:
F1 ();
f2 ();
Wenn F1 eine zeitaufwändige Aufgabe ist, können Sie F1 umschreiben und F2 als Rückruffunktion von F1 schreiben.
Die Codekopie lautet wie folgt:
Funktion F1 (Rückruf) {
setTimeout (function () {
// F1s Aufgabencode
callback ();
}, 1000);
}
Der Ausführungscode wird so:
Die Codekopie lautet wie folgt:
F1 (F2);
Auf diese Weise verwandeln wir synchrone Operationen in asynchrone Operationen. F1 blockiert nicht den Betrieb des Programms, der der Ausführung der Hauptlogik des Programms zuerst und der Ausführung des zeitaufwändigen Betriebs entspricht.
Der Vorteil von Rückruffunktionen besteht darin, dass sie einfach, leicht zu verstehen und bereitzustellen, und der Nachteil ist, dass sie dem Lesen und Wartung von Code nicht förderlich sind. Sie sind stark gekoppelt (Kopplung) zwischen den verschiedenen Teilen, und der Prozess ist sehr chaotisch, und jede Aufgabe kann nur eine Rückruffunktion angeben.
2. Ereignisüberwachung
Eine andere Idee ist es, ein ereignisorientiertes Modell zu übernehmen. Die Ausführung einer Aufgabe hängt nicht von der Reihenfolge des Codes ab, sondern von einer Ereignis.
Nehmen wir F1 und F2 als Beispiele. Binden Sie zunächst ein Ereignis für F1 (die hier verwendete Jquery -Schreibmethode).
Die Codekopie lautet wie folgt:
F1.on ('Done', F2);
Die oben genannte Codezeile bedeutet, dass F2 ausgeführt wird, wenn das Ereignis in F1 auftritt. Schreiben Sie dann F1 neu:
Die Codekopie lautet wie folgt:
Funktion f1 () {
setTimeout (function () {
// F1s Aufgabencode
F1.TRIGGER ('DEM');
}, 1000);
}
F1.Tigger ('Done') bedeutet, dass nach Abschluss der Ausführung das Ereignis sofort ausgelöst wird, wodurch F2 ausgeführt wird.
Der Vorteil dieser Methode besteht darin, dass sie relativ leicht zu verstehen ist. Es kann mehrere Ereignisse binden, und jedes Ereignis kann mehrere Rückruffunktionen angeben, und es kann "Entkopplung" sein, was der Modularisierung förderlich ist. Der Nachteil ist, dass das gesamte Programm ereignisgesteuert wird und der Betriebsprozess sehr unklar wird.
3.. Veröffentlichen/abonnieren
Das "Ereignis" im vorherigen Abschnitt kann als "Signal" vollständig verstanden werden.
Wir gehen davon aus, dass es ein "Signalzentrum" gibt. Nach Abschluss einer Aufgabe wird ein Signal an das Signalcenter veröffentlicht. Andere Aufgaben können das Signal dem Signalzentrum "abonnieren", um zu wissen, wann es mit der Ausführung beginnen kann. Dies wird als "Publish-Subscribe-Muster" bezeichnet, das auch als "Observer-Muster" bezeichnet wird.
Es gibt viele Implementierungen dieses Modells. Das Folgende ist Ben Almans winziges Pub/Sub, das ein Plug-In für JQuery ist.
Erstens zeichnet F2 das "Done" -Signal für das "Signal Center" JQuery ab.
Die Codekopie lautet wie folgt:
JQuery.Subscribe ("Done", F2);
Dann wird F1 wie folgt umgeschrieben:
Die Codekopie lautet wie folgt:
Funktion f1 () {
setTimeout (function () {
// F1s Aufgabencode
JQuery.Publish ("Done");
}, 1000);
}
jQuery.publish ("Done") bedeutet, dass nach Abschluss der F1 -Ausführung ein "Fertig" -Signal an das "Signal Center" JQuery ausgegeben wird, wodurch die Ausführung von F2 ausgelöst wird.
Darüber hinaus kann nach der Ausführung von F2 auch Abmeldungen abgelebt werden.
Die Codekopie lautet wie folgt:
jQuery.unsubscribe ("Done", F2);
Die Art dieser Methode ähnelt dem "Ereignishören", ist jedoch deutlich besser als letzteres. Da wir den Betrieb des Programms überwachen können, indem wir das "Message Center" betrachten, um zu verstehen, wie viele Signale existieren und wie viele Abonnenten für jedes Signal sind.
4. Verspricht Objekt
Das Versprechungsobjekt ist eine von der CommonJS -Arbeitsgruppe vorgeschlagene Spezifikation mit dem Ziel, eine einheitliche Schnittstelle für die asynchrone Programmierung bereitzustellen.
Einfach ausgedrückt ist es die Idee, dass jede asynchrone Aufgabe ein Versprechensobjekt zurückgibt, das eine damalige Methode hat, mit der die Rückruffunktion angegeben werden kann. Beispielsweise kann die Rückruffunktion F2 von F1 geschrieben werden als:
Die Codekopie lautet wie folgt:
f1 (). Dann (F2);
F1 muss wie folgt umgeschrieben werden (die Implementierung von JQuery wird hier verwendet):
Die Codekopie lautet wie folgt:
Funktion f1 () {
var dfd = $ .deferred ();
setTimeout (function () {
// F1s Aufgabencode
dfd.resolve ();
}, 500);
return dfd.Promise;
}
Der Vorteil des Schreibens auf diese Weise besteht darin, dass die Rückruffunktion zu einer Kettenschreibmethode geworden ist und der Programmfluss sehr deutlich zu sehen ist, und es gibt eine vollständige Reihe von Unterstützungsmethoden, die viele leistungsstarke Funktionen realisieren können.
Geben Sie beispielsweise mehrere Rückruffunktionen an:
Die Codekopie lautet wie folgt:
f1 (). Dann (f2) .then (f3);
Geben Sie beispielsweise die Rückruffunktion an, wenn ein Fehler auftritt:
Die Codekopie lautet wie folgt:
f1 (). Dann (F2) .Fail (F3);
Darüber hinaus hat es einen Vorteil, dass keine der vorherigen drei Methoden: Wenn eine Aufgabe erledigt wurde, fügen Sie eine Rückruffunktion hinzu und die Rückruffunktion wird sofort ausgeführt. Sie müssen sich also keine Sorgen machen, ein Ereignis oder ein Signal zu verpassen. Der Nachteil dieser Methode ist, dass es relativ schwer zu schreiben und zu verstehen ist.