Das einzige Problem mit Versprechungen ist, dass der IE sie nicht unterstützt. Edge tut es, aber es gibt viele IE 10 und 11 da draußen: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise (Kompatibilität unten)
JavaScript ist also Single-Threaded. Wenn Sie keinen asynchronen Anruf tätigen, verhält sich dieser vorhersehbar. Der Haupt-JavaScript-Thread führt eine Funktion vollständig aus, bevor die nächste in der Reihenfolge ausgeführt wird, in der sie im Code angezeigt werden. Die Garantie der Reihenfolge für synchrone Funktionen ist trivial - jede Funktion wird vollständig in der Reihenfolge ausgeführt, in der sie aufgerufen wurde.
Stellen Sie sich die synchrone Funktion als atomare Arbeitseinheit vor . Der Haupt-JavaScript-Thread führt es vollständig aus, in der Reihenfolge, in der die Anweisungen im Code erscheinen.
Aber werfen Sie den asynchronen Aufruf wie in der folgenden Situation ein:
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
Das macht nicht was du willst . Es führt sofort Funktion 1, Funktion 2 und Funktion 3 aus. Das Laden von div blinkt und ist weg, während der Ajax-Aufruf bei weitem nicht abgeschlossen ist, obwohl er makeAjaxCall()
zurückgekehrt ist. Die Komplikation ist, dass makeAjaxCall()
die Arbeit in Blöcke aufgeteilt wurde , die nach und nach durch jede Drehung des Haupt-JavaScript-Threads erweitert werden - sie verhält sich asychron. Derselbe Haupt-Thread führte jedoch während eines Drehs / Laufs die synchronen Teile schnell und vorhersehbar aus.
So habe ich damit umgegangen : Wie gesagt, die Funktion ist die atomare Arbeitseinheit. Ich habe den Code von Funktion 1 und 2 kombiniert - ich habe den Code von Funktion 1 vor dem asynchronen Aufruf in Funktion 2 eingefügt. Ich habe Funktion 1 losgeworden. Alles bis einschließlich des asynchronen Aufrufs wird vorhersehbar in der richtigen Reihenfolge ausgeführt.
Wenn der asynchrone Aufruf abgeschlossen ist, rufen Sie nach mehreren Drehungen des JavaScript-Hauptthreads die Funktion 3 auf. Dies garantiert die Reihenfolge . Mit ajax wird beispielsweise der Ereignishandler onreadystatechange mehrmals aufgerufen. Wenn es meldet, dass es abgeschlossen ist, rufen Sie die gewünschte endgültige Funktion auf.
Ich bin damit einverstanden, dass es chaotischer ist. Ich mag es, wenn Code symmetrisch ist, ich mag es, wenn Funktionen eine Sache tun (oder in der Nähe davon), und ich mag es nicht, wenn der Ajax-Aufruf in irgendeiner Weise für die Anzeige verantwortlich ist (wodurch eine Abhängigkeit vom Aufrufer entsteht). ABER bei einem in eine synchrone Funktion eingebetteten asynchronen Aufruf müssen Kompromisse eingegangen werden, um die Ausführungsreihenfolge zu gewährleisten. Und ich muss für IE 10 codieren, also keine Versprechen.
Zusammenfassung : Bei synchronen Anrufen ist die Garantie der Bestellung trivial. Jede Funktion wird vollständig in der Reihenfolge ausgeführt, in der sie aufgerufen wurde. Bei einer Funktion mit einem asynchronen Aufruf besteht die einzige Möglichkeit, die Reihenfolge zu gewährleisten, darin, zu überwachen, wann der asynchrone Aufruf abgeschlossen ist, und die dritte Funktion aufzurufen, wenn dieser Status erkannt wird.
Eine Diskussion der JavaScript-Threads finden Sie unter: https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23 und https://developer.mozilla.org/en-US/docs/Web/JavaScript/ EventLoop
Eine weitere ähnliche, hoch bewertete Frage zu diesem Thema: Wie soll ich 3 Funktionen aufrufen, um sie nacheinander auszuführen?
firstFunction
genau macht es asynchron? So oder so - überprüfen Sie über Versprechen