Heim >Web-Frontend >js-Tutorial >Nodejs-Studie stellt fest, dass globale Objekte global object_node.js sind
1, Eröffnungsanalyse
Im letzten Kapitel haben wir die grundlegenden theoretischen Kenntnisse von NodeJS erlernt. In den folgenden Kapiteln werden wir die verschiedenen Module entsprechend den offiziellen Dokumenten erlernen Damit der Protagonist dieses Artikels die Bühne betritt, Global
Werfen wir einen Blick auf die offizielle Definition:
Globale ObjekteGlobale ObjekteDiese Objekte sind in allen Modulen verfügbar. Einige dieser Objekte befinden sich nicht tatsächlich im globalen Bereich, sondern im Modulbereich – dies wird vermerkt.
Diese Objekte sind in allen Modulen verfügbar. Tatsächlich befinden sich einige Objekte nicht im globalen Bereich, sondern im Modulbereich – diese werden identifiziert.
In Browsern ist der Bereich der obersten Ebene der globale Bereich. Das bedeutet, dass in Browsern, wenn Sie sich im globalen Bereich befinden,var something
eine globale Variable definiert wird.
In Node ist dies anders. Der Bereich der obersten Ebene ist nicht der globale Bereich;var something
innerhalb eines Node-Moduls ist er lokal für dieses Modul.
Ich denke, jeder sollte mit dem Konzept globaler Objekte vertraut sein. Im Browser ist der Bereich der höchsten Ebene der globale Bereich. Wenn Sie also „var“ verwenden, um eine Variable im globalen Bereich zu definieren, wird diese Variable angezeigt definiert als Global Scope.
Aber in NodeJS ist es anders. Der Geltungsbereich der höchsten Ebene ist nicht der globale Geltungsbereich. Verwenden Sie „var“, um eine Variable in einem Modul zu definieren.
In NodeJS sind in einem Modul definierte Variablen, Funktionen oder Methoden nur innerhalb dieses Moduls verfügbar, sie können jedoch mithilfe des Exportobjekts außerhalb des Moduls übergeben werden.
In Node.js gibt es jedoch immer noch einen globalen Bereich, das heißt, Sie können einige Variablen, Funktionen oder Klassen definieren, die verwendet werden können, ohne dass Module geladen werden müssen.
Gleichzeitig sind auch einige globale Methoden und globale Klassen vordefiniert. Das globale Objekt ist der globale Namespace in NodeJS. Jede globale Variable, Funktion oder jedes Objekt ist ein Attributwert des Objekts.
In der REPL-Laufumgebung können Sie die Details im globalen Objekt mithilfe der folgenden Anweisung beobachten, wie in der folgenden Abbildung dargestellt:
Ich werde im Folgenden nacheinander auf die zugehörigen Attributwertobjekte eingehen, die im globalen Objekt eingebunden sind.
(1), Prozess
Prozess {Objekt} Das Prozessobjekt. Siehe den Abschnitt zum Prozessobjekt.
Prozess-{Objekt} Dies ist ein Prozessobjekt. Ich werde in den folgenden Kapiteln näher darauf eingehen, aber hier möchte ich eine API herausnehmen, um darüber zu sprechen.
Process.nextTick(callback)
Rufen Sie in der nächsten Schleife um die Ereignisschleife diesen Rückruf auf. Dies ist kein einfacher Alias für setTimeout(fn, 0), er ist viel effizienter. Er wird normalerweise ausgeführt, bevor andere E/A-Ereignisse ausgelöst werden, aber es gibt einige Ausnahmen. Siehe Process.maxTickDepth unten.
Rufen Sie die Callback-Callback-Funktion in der nächsten Iteration der Ereignisschleife auf. Dies ist kein einfacher Alias für die Funktion setTimeout(fn, 0), da sie viel effizienter ist.
Diese Funktion kann unsere Rückruffunktion vor jeder E/A aufrufen. Diese Funktion ist für Sie sehr wichtig, wenn Sie einige Vorgänge ausführen möchten, nachdem das Objekt erstellt wurde, aber bevor der E/A-Vorgang erfolgt.
Es gibt viele Leute, die die Verwendung von Process.nextTick() in Node.js nicht verstehen. Schauen wir uns an, was Process.nextTick() ist und wie man es verwendet.
Node.js ist Single-Threaded. Zusätzlich zur System-E/A wird während des Ereignisabfrageprozesses nur ein Ereignis gleichzeitig verarbeitet. Sie können sich die Ereignisabfrage als eine große Warteschlange vorstellen. Zu jedem Zeitpunkt verarbeitet das System nur ein Ereignis.
Auch wenn Ihr Computer über mehrere CPU-Kerne verfügt, können Sie nicht mehrere Ereignisse gleichzeitig parallel verarbeiten. Aufgrund dieser Eigenschaft eignet sich node.js jedoch für die Verarbeitung von E/A-Anwendungen, nicht jedoch für CPU-basierte Computeranwendungen.
In jeder E/A-Anwendung müssen Sie nur eine Rückruffunktion für jeden Ein- und Ausgang definieren, und diese werden automatisch zur Verarbeitungswarteschlange der Ereignisabfrage hinzugefügt.
Wenn der E/A-Vorgang abgeschlossen ist, wird diese Rückruffunktion ausgelöst. Das System wird dann mit der Bearbeitung anderer Anfragen fortfahren.
In diesem Verarbeitungsmodus bedeutet „process.nextTick()“, eine Aktion zu definieren und diese Aktion zum nächsten Ereignisabfragezeitpunkt ausführen zu lassen. Schauen wir uns ein Beispiel an. Im Beispiel gibt es ein foo(). Wenn Sie es zum nächsten Zeitpunkt aufrufen möchten, können Sie Folgendes tun:
Führen Sie den obigen Code aus und Sie werden anhand der unten im Terminal gedruckten Informationen sehen, dass die Ausgabe von „bar“ vor „foo“ steht. Dadurch wird die obige Anweisung überprüft. foo() wird zum nächsten Zeitpunkt ausgeführt.
Sie können auch die Funktion setTimeout() verwenden, um scheinbar den gleichen Ausführungseffekt zu erzielen:
Aber in Bezug auf den internen Verarbeitungsmechanismus unterscheiden sich process.nextTick() und setTimeout(fn, 0) nicht um eine einfache Verzögerung, sondern um mehr Funktionen .
Genauer gesagt erstellt der durch process.nextTick() definierte Aufruf einen neuen Substack. Sie können beliebig viele Operationen auf dem aktuellen Stapel ausführen. Aber sobald netxTick aufgerufen wird, muss die Funktion zum übergeordneten Stapel zurückkehren. Anschließend wartet der Ereignisabfragemechanismus darauf, dass neue Ereignisse erneut verarbeitet werden. Wenn ein Aufruf von nextTick gefunden wird, wird ein neuer Stapel erstellt.
Werfen wir einen Blick darauf, wann wir „process.nextTick()“ verwenden sollten:
CPU-intensive Aufgaben über mehrere Ereignisse hinweg ausführen:
Im folgenden Beispiel gibt es eine „compute()“-Funktion. Wir hoffen, dass diese Funktion so kontinuierlich wie möglich ausgeführt wird, um einige rechenintensive Aufgaben auszuführen.
Gleichzeitig hoffen wir aber auch, dass das System durch diese Funktion nicht blockiert wird, sondern auch auf andere Ereignisse reagieren und diese bewältigen muss. Dieses Anwendungsmodell ähnelt einem Single-Threaded-Webdienstserver. Hier können wir „process.nextTick()“ verwenden, um „compute()“ und die normale Ereignisantwort kreuzweise auszuführen.
In diesem Modus müssen wir „compute()“ nicht rekursiv aufrufen. Wir müssen lediglich „process.nextTick()“ in der Ereignisschleife verwenden, um „compute()“ zu definieren, das zum nächsten Zeitpunkt ausgeführt werden soll.
Wenn während dieses Prozesses eine neue HTTP-Anfrage eingeht, verarbeitet der Ereignisschleifenmechanismus zuerst die neue Anfrage und ruft dann compute() auf.
Im Gegenteil, wenn Sie „compute()“ in einen rekursiven Aufruf einfügen, wird das System in „compute()“ immer blockiert und kann keine neuen http-Anfragen verarbeiten. Sie können es selbst versuchen.
Natürlich können wir durch process.nextTick() nicht die tatsächlichen Vorteile der parallelen Ausführung unter mehreren CPUs erzielen. Dadurch wird nur die segmentierte Ausführung derselben Anwendung auf der CPU simuliert.
(2),Konsole
console {Object} Wird zum Drucken auf stdout und stderr verwendet. Siehe den Abschnitt stdio.
Konsolen-{Objekt} wird zum Drucken in der Standardausgabe und Fehlerausgabe verwendet. Siehe den Test unten:
Sie erhalten die folgende Ausgabe:
通过这些函数,我们基本上知道NodeJS在全局作用域添加了些什么内容,其实Console对象上的相关api只是对Process对象上的„stdout.write“对象上.
(3),exports与module.exports
在NodeJS中,有两种作用域,分为全局作用域和模块作用域
我们看到var name = 'var-name';name = 'name'; 是定义的局部变量;
而global.name='global-name';是为 全局对象定义一个name 属性,
而 this.name = 'module-name';是为模块对象定义了一个name 属性
那么我们来验证一下,将下面保存成test2.js,运行
而 t1.name 则是 test1 模块中通过this.name 定义的,说明this 指向 的是 模块作用域对象.
exports与module.exports的一点区别
才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是Module.exports
而不是ex Ports.Module.exports
。当然,这有个前提,就是Module.exports
Module.exports
本身不具备任何属性和方法
。
如果,
Module.exports
已经具备一些属性和方法,那么exports收集来的信息将被忽略。
新建一个文件 bb.js
Referenzieren Sie bb.js und führen Sie es erneut aus
Es ist ersichtlich, dass Ihr Modul nicht unbedingt ein „instanziiertes Objekt“ zurückgeben muss. Ihr Modul kann jedes zulässige JavaScript-Objekt sein – boolescher Wert, Zahl, Datum, JSON, Zeichenfolge, Funktion, Array usw.
(4), setTimeout, setInterval, process.nextTick, setImmediate
Folgendes erscheint in Form einer Zusammenfassung
Nodejs zeichnet sich durch ereignisgesteuerte, hohe Parallelität aus, die durch asynchrone E/A erzeugt wird. Ereignisse werden in entsprechende Ereignisbeobachter, wie z. B. Leerlaufbeobachter, I/O, eingeteilt. O-Beobachter usw. Jeder Zyklus der Ereignisschleife wird als Tick bezeichnet. Jeder Tick holt Ereignisse der Reihe nach aus dem Ereignisbeobachter und verarbeitet sie.
Der beim Aufruf von setTimeout() oder setInterval() erstellte Timer wird im Rot-Schwarz-Baum im Timer-Beobachter platziert. Bei jedem Ticken prüft er, ob der Timer das Timeout vom Rot-Schwarz-Baum überschritten hat . , wenn es überschritten wird, wird die entsprechende Callback-Funktion sofort ausgeführt. Sowohl setTimeout () als auch setInterval () werden als Timer verwendet. Der Unterschied besteht darin, dass letzterer wiederholt ausgelöst wird. Da die Zeit zu kurz eingestellt ist, wird die Verarbeitung nach dem vorherigen Trigger sofort nach Abschluss der Verarbeitung ausgelöst.
Da der Timer durch Timeout ausgelöst wird, führt dies zu einer verringerten Auslösegenauigkeit. Beispielsweise beträgt das mit setTimeout festgelegte Timeout 5 Sekunden, wenn die Ereignisschleife eine Aufgabe in der 4. Sekunde durchläuft und ihre Ausführungszeit 3 Sekunden beträgt , Dann läuft die Rückruffunktion setTimeout in 2 Sekunden ab, was der Grund für die verringerte Genauigkeit ist. Und weil der Rot-Schwarz-Baum und die Iterationsmethoden zum Speichern von Timern und zum Bestimmen von Auslösern verwendet werden, ist dies eine Leistungsverschwendung.
Alle mit „process.nextTick()“ festgelegten Rückruffunktionen werden im Array platziert und alle werden sofort beim nächsten Tick ausgeführt. Dieser Vorgang ist relativ leichtgewichtig und weist eine hohe Zeitgenauigkeit auf.
Die von setImmediate() festgelegte Callback-Funktion wird auch beim nächsten Tick aufgerufen. Der Unterschied zwischen ihr undprocess.nextTick() liegt in zwei Punkten:
1. Die Beobachter, zu denen sie gehören, werden mit unterschiedlichen Prioritäten ausgeführt. Process.nextTick() gehört zum Leerlaufbeobachter, setImmediate() gehört zum Prüfbeobachter und die Priorität des Leerlaufs > prüft.
2. Die von setImmediate() festgelegte Rückruffunktion wird in einer verknüpften Liste platziert. Jeder Tick führt nur einen Rückruf in der verknüpften Liste aus. Dadurch soll sichergestellt werden, dass jeder Tick schnell ausgeführt werden kann.
Zweitens: Fassen Sie zusammen
1. Verstehen Sie die Bedeutung der Existenz globaler Objekte
2. Ein kleiner Unterschied zwischen Exports und module.exports
3. Was ist die zugrunde liegende Struktur der Konsole (Kapselung des Prozessobjekts auf hoher Ebene)
4. Der Unterschied zwischen setTimeout, setInterval, process.nextTick und setImmediate
5. Zwei Arten von Bereichen in NodeJS