Async Hooks ist eine neue Funktion von Node8. Sie bietet einige APIs zur Verfolgung des Lebenszyklus asynchroner Ressourcen in NodeJs. Es ist ein integriertes Modul von NodeJs und kann direkt referenziert werden. const async_hooks = erfordern('async_hooks'); Dies ist ein selten verwendetes Modul. Warum existiert es? Wir alle wissen, dass JavaScript von Anfang an als Single-Thread-Sprache konzipiert wurde. Dies hängt mit seiner ursprünglichen Designabsicht zusammen. Das ursprüngliche JavaScript wurde nur verwendet, um Formularüberprüfungen auf der Seite durchzuführen, um den Zeitaufwand der Benutzer zu reduzieren, die in Zeiten niedriger Netzwerkgeschwindigkeit auf Serverantworten warten. Obwohl die Front-End-Funktionen mit der Entwicklung der Web-Frontend-Technologie immer leistungsfähiger und wichtiger werden, scheint es kein Problem zu geben, das Single-Threading nicht lösen kann. Im Vergleich dazu scheint Multi-Threading komplizierter zu sein, sodass Single-Threading auch heute noch verwendet wird. Da JavaScript ein Single-Thread ist, gibt es bei der täglichen Entwicklung immer einige zeitaufwändige Aufgaben, wie Timer und das mittlerweile standardisierte Ajax. Um diese Probleme zu lösen, unterteilt sich JavaScript in BOM, DOM und ECMAScript. BOM hilft uns bei der Lösung dieser zeitaufwändigen Aufgaben, die als asynchrone Aufgaben bezeichnet werden. Da uns die BOM des Browsers bei der Verarbeitung asynchroner Aufgaben hilft, wissen die meisten Programmierer fast nichts über asynchrone Aufgaben, außer wie man sie verwendet. Wie viele asynchrone Aufgaben befinden sich beispielsweise gleichzeitig in der Warteschlange? Wir haben keine Möglichkeit, relevante Informationen direkt abzurufen, etwa ob der asynchrone Prozess überlastet ist. In vielen Fällen erfordert die zugrunde liegende Schicht nicht, dass wir auf relevante Informationen achten. Wenn wir jedoch in einigen Fällen relevante Informationen benötigen, stellt NodeJS eine experimentelle API zur Verfügung, die wir verwenden können: async_hooks. Warum NodeJS? Weil nur in Node asynchrone Module wie Timer und http von Entwicklern gesteuert werden können. Das BOM im Browser wird nicht von Entwicklern gesteuert, es sei denn, der Browser stellt die entsprechende API bereit. async_hooks-Regeln async_hooks legt fest, dass jede Funktion einen Kontext bereitstellt, den wir als asynchronen Bereich bezeichnen. Jeder asynchrone Bereich hat eine asyncId, die das Logo des aktuellen asynchronen Bereichs ist. Die asyncId im selben asynchronen Bereich muss dieselbe sein. Wenn mehrere asynchrone Aufgaben parallel ausgeführt werden, können wir mithilfe von asyncId unterscheiden, welche asynchrone Aufgabe überwacht werden soll. asyncId ist eine selbsterhöhende, sich nicht wiederholende positive Ganzzahl. Die erste asyncId eines Programms muss 1 sein. Einfach ausgedrückt ist der asynchrone Bereich eine synchrone Aufgabe, die nicht unterbrochen werden kann. Solange sie nicht unterbrochen werden kann, wird unabhängig von der Länge des Codes eine asynchrone ID gemeinsam genutzt. Wenn sie jedoch in der Mitte unterbrochen werden kann, z. B. durch einen Rückruf oder ein Warten in der Mitte, wird ein neuer asynchroner Kontext erstellt und eine neue asynchrone ID wird erstellt. Jeder asynchrone Bereich verfügt über eine „triggerAsyncId“, die angibt, dass die aktuelle Funktion durch diesen asynchronen Bereich ausgelöst wird. Über asyncId und triggerAsyncId können wir die gesamte asynchrone Anrufbeziehung und -verknüpfung problemlos verfolgen. async_hooks.executionAsyncId() wird verwendet, um die asyncId abzurufen. Sie können sehen, dass die globale asyncId 1 ist. async_hooks.triggerAsyncId() wird verwendet, um triggerAsyncId zu erhalten, und sein aktueller Wert ist 0. const async_hooks = erfordern('async_hooks'); console.log('asyncId:', async_hooks.executionAsyncId()); // asyncId: 1 console.log('triggerAsyncId:', async_hooks.triggerAsyncId()); // triggerAsyncId: 0 Wir verwenden fs.open, um hier eine Datei zu öffnen. Wir können feststellen, dass die asyncId von fs.open 7 ist und die triggerAsyncId von fs.open 1 wird. Dies liegt daran, dass fs.open durch einen globalen Aufruf ausgelöst wird und die globale asyncId 1 ist. const async_hooks = erfordern('async_hooks'); console.log('asyncId:', async_hooks.executionAsyncId()); // asyncId: 1 console.log('triggerAsyncId:', async_hooks.triggerAsyncId()); // triggerAsyncId: 0 const fs = erfordern('fs'); fs.open('./test.js', 'r', (err, fd) => { console.log('fs.open.asyncId:', async_hooks.executionAsyncId()); // 7 console.log('fs.open.triggerAsyncId:', async_hooks.triggerAsyncId()); // 1 }); Der Lebenszyklus einer asynchronen Funktion Natürlich wird async_hooks in tatsächlichen Anwendungen nicht auf diese Weise verwendet. Die korrekte Verwendung besteht darin, Rückrufe vor, nach und nach dem Erstellen, Ausführen und Löschen aller asynchronen Aufgaben auszulösen, und alle Rückrufe werden in asyncId übergeben. Wir können async_hooks.createHook verwenden, um einen asynchronen Ressourcen-Hook zu erstellen, der ein Objekt als Parameter empfängt, um einige Rückruffunktionen für Ereignisse zu registrieren, die im Lebenszyklus asynchroner Ressourcen auftreten können. Diese Hook-Funktionen werden jedes Mal ausgelöst, wenn eine asynchrone Ressource erstellt/ausgeführt/zerstört wird. const async_hooks = erfordern('async_hooks'); const asyncHook = async_hooks.createHook({ init(asyncId, Typ, triggerAsyncId, Ressource) { }, zerstören(asyncId) { } }) Derzeit kann die Funktion createHook die folgenden fünf Typen von Hook-Callbacks akzeptieren: 1. init(asyncId, Typ, triggerAsyncId, Ressource)
Wir können die Funktion async_hooks.createHook verwenden, um Listener-Funktionen für init/before/after/destory/promiseResolve und andere verwandte Ereignisse zu registrieren, die im Lebenszyklus jeder asynchronen Ressource auftreten. 2. vorher(asyncId) Die Funktion „Before“ wird im Allgemeinen aufgerufen, nachdem der asynchrone Ressourcenvorgang, der asyncId entspricht, abgeschlossen ist und bevor der Rückruf ausgeführt wird. Die Funktion „Before“ kann mehrmals ausgeführt werden, was durch die Anzahl der Rückrufe bestimmt wird. Bitte beachten Sie dies bei der Verwendung. 3.nach(asyncId) Die After-Callback-Funktion wird im Allgemeinen unmittelbar aufgerufen, nachdem die asynchrone Ressource die Callback-Funktion ausgeführt hat. Wenn während der Ausführung der Callback-Funktion eine nicht abgefangene Ausnahme auftritt, wird das After-Ereignis aufgerufen, nachdem das Ereignis „uncaughtException“ ausgelöst wurde. 4.zerstören(asynchroneID) Wird aufgerufen, wenn die asynchrone Ressource, die asyncId entspricht, zerstört wird. Die Zerstörung einiger asynchroner Ressourcen hängt vom Garbage Collection-Mechanismus ab. In einigen Fällen wird das Zerstörungsereignis aufgrund von Speicherlecks möglicherweise nie ausgelöst. 5. VersprechenResolve(asyncId) Wenn die Resolve-Funktion im Promise-Konstruktor ausgeführt wird, wird das PromiseResolve-Ereignis ausgelöst. In einigen Fällen werden einige Resolve-Funktionen implizit ausgeführt. Beispielsweise gibt die Funktion .then ein neues Promise zurück, das zu diesem Zeitpunkt ebenfalls aufgerufen wird. const async_hooks = erfordern('async_hooks'); // Holen Sie sich die asyncId des aktuellen Ausführungskontexts const eid = async_hooks.executionAsyncId(); // Holen Sie sich die asyncId, die die aktuelle Funktion auslöst const tid = async_hooks.triggerAsyncId(); // Erstellen Sie eine neue AsyncHook-Instanz. Alle diese Rückrufe sind optional const asyncHook = async_hooks.createHook({ init, vorher, nachher, zerstören, promiseResolve }); //AsyncHook.enable() muss zur Ausführung deklariert werden; // Deaktivieren Sie das Abhören neuer asynchroner Ereignisse. asyncHook.disable(); Funktion init(asyncId, Typ, triggerAsyncId, Ressource) { } Funktion vor (asyncId) { } Funktion nach (asyncId) { } Funktion zerstören(asyncId) { } Funktion promiseResolve(asyncId) { } Versprechen Promise ist ein Sonderfall. Wenn Sie genau genug hinschauen, werden Sie feststellen, dass im Typ der Init-Methode kein PROMISE vorhanden ist. Wenn Sie nur ah.executionAsyncId() verwenden, um die asyncId von Promise abzurufen, können Sie nicht die richtige ID erhalten. Erst nach dem Hinzufügen des eigentlichen Hooks erstellt async_hooks eine asyncId für den Promise-Rückruf. Mit anderen Worten: Da V8 hohe Ausführungskosten für das Abrufen von asyncId verursacht, weisen wir Promise standardmäßig keine neue asyncId zu. const async_hooks = erfordern('async_hooks'); const asyncHook = async_hooks.createHook({ init(asyncId, Typ, triggerAsyncId, Ressource) { }, zerstören(asyncId) { } }) asyncHook.enable(); Versprechen.resolve(123).then(() => { console.log(`asyncId ${async_hooks.executionAsyncId()} triggerId ${async_hooks.triggerAsyncId()}`); }); Darüber hinaus löst Promise nur die Hook-Ereignisfunktionen „init“ und „promiseResolve“ aus, und die Hook-Funktionen der Ereignisse „vorher“ und „nachher“ werden nur ausgelöst, wenn Promise verkettet ist, d. h. sie werden nur ausgelöst, wenn Promise in der Funktion .then/.catch generiert wird. neues Versprechen(lösen => { Entschlossenheit (123); }).dann(Daten => { konsole.log(Daten); }) Es ist ersichtlich, dass es oben zwei Promises gibt, das erste wird durch eine neue Instanziierung erstellt und das zweite wird bis dahin erstellt (wenn Sie es nicht verstehen, können Sie den vorherigen Artikel zum Promise-Quellcode lesen). Die Reihenfolge ist hier, dass beim Ausführen eines neuen Promise seine eigene Init-Funktion aufgerufen wird und dann beim Auflösen die Funktion promiseResolve aufgerufen wird. Führen Sie dann die Init-Funktion des zweiten Promise in der Then-Methode aus und führen Sie dann die Funktionen Before, PromiseResovle und After des zweiten Promise aus. Ausnahmebehandlung Wenn in der registrierten Async-Hook-Callback-Funktion eine Ausnahme auftritt, druckt der Dienst ein Fehlerprotokoll und wird sofort beendet. Gleichzeitig werden alle Listener entfernt und das Ereignis „exit“ ausgelöst, um das Programm zu beenden. Der Grund, warum der Prozess sofort beendet wird, ist, dass, wenn diese asynchronen Hook-Funktionen instabil laufen, wahrscheinlich eine Ausnahme ausgelöst wird, wenn das nächste gleiche Ereignis ausgelöst wird. Diese Funktionen werden hauptsächlich zur Überwachung asynchroner Ereignisse verwendet. Wenn sie instabil sind, sollten sie rechtzeitig entdeckt und korrigiert werden. Drucken von Protokollen in asynchronen Hook-Rückrufen Da die Funktion console.log ebenfalls ein asynchroner Aufruf ist, wird das entsprechende Hook-Ereignis erneut ausgelöst, wenn wir console.log in der asynchronen Hook-Funktion erneut aufrufen, was zu einem Aufruf in einer Endlosschleife führt. Daher müssen wir synchrones Logging verwenden, um die asynchrone Hook-Funktion zu verfolgen. Wir können die Funktion fs.writeSync verwenden: const fs = erfordern('fs'); const util = erfordern('util'); Funktion debug(...args) { fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' }); } [Referenzen - AsyncHooks] (https://nodejs.org/dist/latest-v15.x/docs/api/async_hooks.html) Dies ist das Ende dieses Artikels über den asynchronen Lebenszyklus von AsyncHooks in Node8. Weitere relevante Inhalte zum asynchronen Lebenszyklus von Node AsyncHooks finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die verwandten Artikel weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Alibaba Cloud Centos7 Installation und Konfiguration von SVN
>>: mysql5.7 Installations- und Konfigurationstutorial unter Centos7.3
Ich habe vor Kurzem Docker gelernt und stoße dabe...
1: MySql herunterladen Offizielle Download-Adress...
MySQL bietet mehrere Möglichkeiten, mehrere SQL-D...
1. Übersicht über das Ansichtsfenster Mobile Brow...
Inhaltsverzeichnis 1. Knoten installieren 2. Inst...
In diesem Artikelbeispiel wird der spezifische Co...
Inhaltsverzeichnis 1. Was ist eine Veranstaltung?...
Mithilfe der Vue-Sprache und Elementkomponenten m...
Vor Kurzem habe ich Apache auf nginx umgestellt. ...
dl: Definitionsliste Definitionsliste dt: Definiti...
Tastaturzeichen Englisch ` Rückwärtszitat ~ Tilde...
Obwohl Microsoft T4-Vorlagen bereitstellt, finde ...
Vorwort Vor kurzem bin ich auf ein interessantes ...
1. Bedeutung der Partitionstabelle Eine Partition...
MySQL 4.x und höher bieten Unterstützung für die ...