


Implementierungsmethode zum zyklischen Laden von JavaScript-Modulen_Javascript-Fähigkeiten
„Zirkuläre Abhängigkeit“ bedeutet, dass die Ausführung von Skript a von Skript b abhängt und die Ausführung von Skript b von Skript a abhängt.
1 2 3 4 5 |
|
Normalerweise weist „Schleifenladen“ auf das Vorhandensein einer starken Kopplung hin. Wenn es nicht richtig gehandhabt wird, kann es auch zu rekursivem Laden führen, wodurch das Programm nicht ausgeführt werden kann. Daher sollte es vermieden werden.
Tatsächlich ist dies jedoch schwer zu vermeiden, insbesondere bei großen Projekten mit komplexen Abhängigkeiten. Es ist leicht, dass a von b, b bis c und c von a abhängt. Dies bedeutet, dass der Modullademechanismus „Loop-Loading“-Situationen berücksichtigen muss.
In diesem Artikel wird erläutert, wie die JavaScript-Sprache mit dem „Schleifenladen“ umgeht. Derzeit verfügen die beiden gängigsten Modulformate CommonJS und ES6 über unterschiedliche Verarbeitungsmethoden und liefern unterschiedliche Ergebnisse.
1. Ladeprinzip des CommonJS-Moduls
Bevor wir vorstellen, wie ES6 das „Schleifenladen“ handhabt, stellen wir zunächst das Ladeprinzip des beliebtesten CommonJS-Modulformats vor.
Ein Modul von CommonJS ist eine Skriptdatei. Wenn der Befehl require das Skript zum ersten Mal lädt, führt er das gesamte Skript aus und generiert dann ein Objekt im Speicher.
1 2 3 4 5 6 |
|
Im obigen Code ist das id-Attribut des Objekts der Modulname, das exports-Attribut ist jede vom Modul ausgegebene Schnittstelle und das geladene Attribut ist ein boolescher Wert, der angibt, ob das Skript des Moduls ausgeführt wurde. Es gibt viele weitere Attribute, die hier jedoch weggelassen werden. (Eine ausführliche Einführung finden Sie unter „require() Quellcode-Interpretation“.)
Wenn Sie dieses Modul in Zukunft verwenden müssen, erhalten Sie den Wert aus dem Exportattribut. Selbst wenn der Befehl require erneut ausgeführt wird, wird das Modul nicht erneut ausgeführt, sondern der Wert wird aus dem Cache abgerufen.
2. Schleifenladen des CommonJS-Moduls
Eine wichtige Funktion des CommonJS-Moduls ist die Ausführung beim Laden, d. h. der gesamte Skriptcode wird bei Bedarf ausgeführt. Der Ansatz von CommonJS besteht darin, dass, sobald ein Modul „in einer Schleife geladen“ ist, nur der ausgeführte Teil ausgegeben wird und der nicht ausgeführte Teil nicht ausgegeben wird.
Werfen wir einen Blick auf die Beispiele in der offiziellen Dokumentation. Der Code der Skriptdatei a.js lautet wie folgt.
1 2 3 4 5 |
|
Im obigen Code gibt das a.js-Skript zuerst eine fertige Variable aus und lädt dann eine andere Skriptdatei b.js. Beachten Sie, dass der a.js-Code zu diesem Zeitpunkt hier stoppt und darauf wartet, dass b.js die Ausführung abschließt, und dann die Ausführung fortsetzt.
Sehen Sie sich den b.js-Code noch einmal an.
1 2 3 4 5 |
|
Wenn im obigen Code b.js bis zur zweiten Zeile ausgeführt wird, wird a.js geladen. Zu diesem Zeitpunkt erfolgt das „Schleifenladen“. Das System erhält den Wert des Exportattributs des Objekts, das dem a.js-Modul entspricht. Da a.js jedoch noch nicht ausgeführt wurde, kann nur der ausgeführte Teil vom Exportattribut abgerufen werden, nicht der endgültige Wert.
Der ausgeführte Teil von a.js hat nur eine Zeile.
exports.done = false;
Daher wird für b.js nur eine Variable eingegeben, die aus a.js stammt, und der Wert ist falsch.
Dann wird b.js weiter ausgeführt. Wenn alle Ausführungen abgeschlossen sind, wird das Ausführungsrecht an a.js zurückgegeben. Daher wird a.js so lange ausgeführt, bis die Ausführung abgeschlossen ist. Wir schreiben ein Skript main.js, um diesen Prozess zu überprüfen.
1 2 3 |
|
Führen Sie main.js aus und die Ergebnisse sind wie folgt.
1 2 3 4 5 6 7 |
|
Der obige Code beweist zwei Dinge. Erstens wurde in b.js nicht a.js ausgeführt, sondern nur die erste Zeile. Zweitens: Wenn main.js bis zur zweiten Zeile ausgeführt wird, wird b.js nicht erneut ausgeführt, sondern das zwischengespeicherte Ausführungsergebnis von b.js wird ausgegeben, dh die vierte Zeile.
exports.done = true;
3. Schleifenladen von ES6-Modulen
Der Betriebsmechanismus von ES6-Modulen unterscheidet sich von CommonJS. Wenn der Modulladebefehl importiert wird, wird das Modul nicht ausgeführt, sondern nur eine Referenz generiert. Warten Sie, bis Sie es wirklich benötigen, und rufen Sie dann den Wert im Modul ab.
Daher sind ES6-Module dynamische Referenzen, es gibt kein Problem beim Zwischenspeichern von Werten und die Variablen im Modul sind an das Modul gebunden, in dem sie sich befinden. Bitte sehen Sie sich das Beispiel unten an.
1 2 3 4 5 6 7 8 |
|
Im obigen Code ist die Variable foo von m1.js gleich bar, wenn sie zum ersten Mal geladen wird. Nach 500 Millisekunden wird sie wieder gleich baz.
Mal sehen, ob m2.js diese Änderung richtig lesen kann.
1 2 3 4 |
|
Der obige Code zeigt, dass das ES6-Modul die laufenden Ergebnisse nicht zwischenspeichert, sondern dynamisch den Wert des geladenen Moduls erhält und die Variable immer an das Modul gebunden ist, in dem sie sich befindet.
Dies führt dazu, dass ES6 das „Schleifenladen“ wesentlich anders handhabt als CommonJS. ES6 kümmert sich überhaupt nicht darum, ob ein „Schleifenladen“ auftritt, es generiert lediglich einen Verweis auf das geladene Modul. Der Entwickler muss sicherstellen, dass der Wert abgerufen werden kann, wenn der Wert tatsächlich abgerufen wird.
Bitte sehen Sie sich das folgende Beispiel an (Auszug aus „Exploring ES6“ von Dr. Axel Rauschmayer).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
按照CommonJS规范,上面的代码是没法执行的。a先加载b,然后b又加载a,这时a还没有任何执行结果,所以输出结果为null,即对于b.js来说,变量foo的值等于null,后面的foo()就会报错。
但是,ES6可以执行上面的代码。
$ babel-node a.js
执行完毕
a.js之所以能够执行,原因就在于ES6加载的变量,都是动态引用其所在的模块。只要引用是存在的,代码就能执行。
我们再来看ES6模块加载器SystemJS给出的一个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
上面代码中,even.js里面的函数foo有一个参数n,只要不等于0,就会减去1,传入加载的odd()。odd.js也会做类似操作。
运行上面这段代码,结果如下。
1 2 3 4 5 6 7 8 9 10 |
|
上面代码中,参数n从10变为0的过程中,foo()一共会执行6次,所以变量counter等于6。第二次调用even()时,参数n从20变为0,foo()一共会执行11次,加上前面的6次,所以变量counter等于17。
这个例子要是改写成CommonJS,就根本无法执行,会报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
上面代码中,even.js加载odd.js,而odd.js又去加载even.js,形成"循环加载"。这时,执行引擎就会输出even.js已经执行的部分(不存在任何结果),所以在odd.js之中,变量even等于null,等到后面调用even(n-1)就会报错。
1 2 3 4 |
|
[说明] 本文是我写的《ECMAScript 6入门》第20章《Module》中的一节。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

JavaScript ist der Eckpfeiler der modernen Webentwicklung. Zu den Hauptfunktionen gehören eine ereignisorientierte Programmierung, die Erzeugung der dynamischen Inhalte und die asynchrone Programmierung. 1) Ereignisgesteuerte Programmierung ermöglicht es Webseiten, sich dynamisch entsprechend den Benutzeroperationen zu ändern. 2) Die dynamische Inhaltsgenerierung ermöglicht die Anpassung der Seiteninhalte gemäß den Bedingungen. 3) Asynchrone Programmierung stellt sicher, dass die Benutzeroberfläche nicht blockiert ist. JavaScript wird häufig in der Webinteraktion, der einseitigen Anwendung und der serverseitigen Entwicklung verwendet, wodurch die Flexibilität der Benutzererfahrung und die plattformübergreifende Entwicklung erheblich verbessert wird.

Es gibt kein absolutes Gehalt für Python- und JavaScript -Entwickler, je nach Fähigkeiten und Branchenbedürfnissen. 1. Python kann mehr in Datenwissenschaft und maschinellem Lernen bezahlt werden. 2. JavaScript hat eine große Nachfrage in der Entwicklung von Front-End- und Full-Stack-Entwicklung, und sein Gehalt ist auch beträchtlich. 3. Einflussfaktoren umfassen Erfahrung, geografische Standort, Unternehmensgröße und spezifische Fähigkeiten.

Wie fusioniere ich Array -Elemente mit derselben ID in ein Objekt in JavaScript? Bei der Verarbeitung von Daten begegnen wir häufig die Notwendigkeit, dieselbe ID zu haben ...

JavaScript zu lernen ist nicht schwierig, aber es ist schwierig. 1) Verstehen Sie grundlegende Konzepte wie Variablen, Datentypen, Funktionen usw. 2) Beherrschen Sie die asynchrone Programmierung und implementieren Sie sie durch Ereignisschleifen. 3) Verwenden Sie DOM -Operationen und versprechen Sie, asynchrone Anfragen zu bearbeiten. 4) Vermeiden Sie häufige Fehler und verwenden Sie Debugging -Techniken. 5) Die Leistung optimieren und Best Practices befolgen.

Diskussion über die Realisierung von Parallaxe -Scrolling- und Elementanimationseffekten in diesem Artikel wird untersuchen, wie die offizielle Website der Shiseeido -Website (https://www.shiseeido.co.jp/sb/wonderland/) ähnlich ist ...

Eingehende Diskussion der Ursachen des Unterschieds in der Konsole.log-Ausgabe. In diesem Artikel wird die Unterschiede in den Ausgabeergebnissen der Konsolenfunktion in einem Code analysiert und die Gründe dafür erläutert. � ...

Erforschen Sie die Implementierung der Funktion des Bedien- und Drop-Einstellungsfunktion der Panel ähnlich wie VSCODE im Front-End. In der Front-End-Entwicklung wird VSCODE ähnlich wie VSCODE implementiert ...
