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 ist, dass es relativ einfach ist und die Ausführungsumgebung relativ einfach ist. Ausführung des gesamten Programms. 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).
"Synchronous -Modus" ist der Modus des vorherigen Abschnitts, und die letztere Aufgabe wartet auf das Ende der vorherigen Aufgabe und führt dann die Ausführungsreihenfolge des Programms aus und synchron mit der Anordnung von Aufgaben völlig anders, und jede Aufgabe ist, dass es eine oder mehrere Rückruffunktionen (Rückrufe) gibt. Zum Ende ist die Ausführungsreihenfolge des Programms und die Aufgabe.
"Async -Modus" ist sehr wichtig. Auf der Browser-Seite sollten langfristige Operationen asynchron ausgeführt werden, um zu vermeiden, dass der Browser die Reaktion verliert. 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.
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:
F1 (F2);
Der Vorteil von Rückruffunktionen ist, dass sie einfach, leicht zu verstehen und bereitzustellen, und der Nachteil ist, dass sie nicht für das Lesen und die Wartung von Code förderlich sind. 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 ist, dass sie relativ einfach zu verstehen 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 "Signalcenter" gibt. Dies wird als "Publish-Subscribe-Muster" bezeichnet, auch als "Observer-Muster" bezeichnet.
Es gibt viele Implementierungen dieses Modells.
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.
Nach der Ausführung von F2 kann auch ein Abbestellen abgesagt werden.
Die Codekopie lautet wie folgt:
jQuery.unsubscribe ("Done", F2);
Die Art dieses Ansatzes ä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:
f1 (). Dann (f2) .then (f3);
Geben Sie beispielsweise die Rückruffunktion an, wenn ein Fehler auftritt:
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.