JS Asynchronous Stack Tracing: Warum „await“ besser ist als „Promise“

JS Asynchronous Stack Tracing: Warum „await“ besser ist als „Promise“

Überblick

Der grundlegende Unterschied zwischen async/await und Promise besteht darin, dass await fn() die Ausführung der aktuellen Funktion unterbricht, während promise.then(fn) die Ausführung der aktuellen Funktion fortsetzt, nachdem der fn-Aufruf zur Rückrufkette hinzugefügt wurde.

const fn = () => console.log('hallo')
const a = async () => {
  warte auf fn() // Ausführung von fn anhalten }
// Wenn a aufgerufen wird, wird die Ausführung von fn fortgesetzt a() // "hallo"

const Versprechen = Versprechen.lösen()
//Nachdem fn zur Rückrufkette hinzugefügt wurde, führe weiterhin fn aus.
promise.then(fn) // "hallo"

Im Kontext eines Stacktraces ist dieser Unterschied sehr bedeutsam.

Wenn eine Promise-Kette (ob desugared oder nicht) zu irgendeinem Zeitpunkt eine unbehandelte Ausnahme auslöst, zeigt die JavaScript-Engine eine Fehlermeldung an und protokolliert (hoffentlich) einen nützlichen Stacktrace.

Als Entwickler erwarten Sie dies, unabhängig davon, ob Sie normale Promises oder asynchrones Warten verwenden.

Versprechen

Stellen Sie sich ein Szenario vor, in dem beim Auflösen des Aufrufs der asynchronen Funktion b die Funktion c aufgerufen wird:

const b = () => Promise.resolve()
const a = () => {
    b().dann(() => c())
}

Beim Aufruf von geschieht folgendes synchron:

  • b wird aufgerufen und gibt ein Promise zurück, das irgendwann in der Zukunft eingelöst wird.
  • Der .then-Rückruf (der eigentlich c() aufruft) wird der Rückrufkette hinzugefügt (in V8-Begriffen wird [...] als Resolve-Handler hinzugefügt).

Danach führen wir die Ausführung des Codes im Hauptteil der Funktion a aus. A wird nie angehalten und bis der asynchrone Aufruf von B aufgelöst ist, ist der Kontext verschwunden.

Stellen Sie sich vor, was passieren würde, wenn b (oder c) asynchron eine Ausnahme auslösen würde? Im Idealfall sollte der Stacktrace A enthalten, da B (oder C) von dort aufgerufen wurde, oder? Wie können wir dies jetzt tun, da wir uns nicht mehr auf ein a beziehen?

Damit dies funktioniert, muss die JavaScript-Engine über die oben genannten Schritte hinaus noch etwas anderes tun: Sie erfasst und speichert den Stacktrace, wann immer sie die Möglichkeit dazu hat.

In V8 wird der Stacktrace an das von b zurückgegebene Promise angehängt. Wenn das Versprechen erfüllt ist, wird der Stapelüberwachungscode weitergegeben, sodass C ihn nach Bedarf verwenden kann.

b()[a] -> b().dann()[a] -> c[a?:a]

Das Erfassen von Stapeltraces nimmt Zeit in Anspruch (d. h. es verlangsamt die Leistung); das Speichern dieser Stapeltraces erfordert Speicher.

asynchron/warten

Hier ist dasselbe Programm, geschrieben mit async/await anstelle von Promises:

const b = () => Promise.resolve()
const a = async () => {
  warte auf b()
  C()
}

Mit „await“ können wir die Aufrufkette fortsetzen, auch wenn der Stapelüberwachungsverlauf im „await“-Aufruf nicht erfasst wird.

Dies ist möglich, weil A angehalten ist und auf die Lösung von B wartet. Wenn b eine Exception wirft, lässt sich auf diese Weise bei Bedarf der Stacktrace rekonstruieren.

Wenn c eine Ausnahme wirft, kann der Stapelüberwachungsvorgang genauso wie für eine synchrone Funktion erstellt werden, da wir uns immer noch im Kontext von a befinden, wenn dies geschieht.

Ermöglichen Sie JavaScript-Engines eine effizientere Verarbeitung von Stacktraces, indem Sie die folgenden Empfehlungen befolgen:

  • Bevorzugen Sie async/await gegenüber Promises.
  • Verwenden Sie @babel/preset env, um unnötige asynchrone/wartende Übertragungen zu vermeiden.

Oben finden Sie Einzelheiten zum asynchronen Stack Tracing von JS und warum „await“ besser ist als „Promise“. Weitere Informationen zu Javascript finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • So implementieren Sie asynchrone Aufrufe mit async/await in JS
  • NodeJs verarbeitet asynchrone Methoden über async/await
  • async/await und promise (Problem mit asynchronem Betrieb in nodejs)
  • Kann Asynchronität in JavaScript „Await“ speichern?

<<:  Tutorial zum Herunterladen, Installieren, Konfigurieren und Verwenden von MySQL unter Windows

>>:  Lösen Sie das Problem, dass WLAN und Audio nach der Windows Server-Installation nicht funktionieren

Artikel empfehlen

jQuery erzielt einen Bildlaufwiedergabeeffekt auf großem Bildschirm

In diesem Artikel wird der spezifische Code von j...

Rendern im Vue-Scaffolding verstehen

Im Vue-Gerüst können wir sehen, dass im neuen Vue...

Fähigkeiten zur Seiten-Refaktorierung - Inhalt

Genug des Smalltalks <br />Basierend auf de...

Einführung in die Verwendung des HTML-Elements Noscript

Noscript-Definition und -Verwendung Das Noscript-...

Detailliertes Tutorial zur Installation des Quellcodes von CentOS6.9+Mysql5.7.18

Bei der Installation des Quellcodes von CentOS6.9...

Gängige Methoden und Probleme der Docker-Bereinigung

Wenn Sie Docker für die Entwicklung im großen Maß...

So implementieren Sie Sveltes Defer Transition in Vue

Ich habe mir vor Kurzem Rich Harris‘ Video „Rethi...

Python3.6-MySql Dateipfad einfügen, die Lösung zum Entfernen des Backslashs

Wie unten dargestellt: Ersetzen Sie es einfach, w...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.6.22

In diesem Tutorial wird der spezifische Code der ...

Analyse der Unfallursachen durch Unicode-Signatur BOM

Möglicherweise verwenden Sie hier Include-Dateien,...

Einführung in das Batch-Cache-Löschskript von nginx proxy_cache

Vorwort: Ich habe zuvor den offiziellen Proxy-Cac...

Methoden und Vorschläge zur Uniapp-Projektoptimierung

Inhaltsverzeichnis 1. Kapseln Sie komplexe Seiten...

Prinzip des MySQL-Indexfehlers

Inhaltsverzeichnis 1. Gründe für Indexfehler 2. S...

So konfigurieren Sie einen Pfadalias für das React-Scaffolding

Die React-Version beim Schreiben dieses Artikels ...

Vue implementiert einfache Rechnerfunktion

In diesem Artikelbeispiel wird der spezifische Co...