Detaillierte Erläuterung von Beispielen für die js-Ereignisschleife
Ich habe schon einige Event-Loop-Blogs gelesen, aber nachdem ich sie eine Weile nicht gelesen hatte, wurde mir klar, dass ich sie alle vergessen hatte, also beschloss ich, einen Blog zu schreiben, um sie zusammenzufassen!
Erklären wir zunächst, was die Ereignisschleife ist:
Soweit wir wissen, ist das Js des Browsers Single-Threaded, d. h Beispielsweise wird höchstens ein Codesegment gleichzeitig ausgeführt, aber der Browser kann asynchrone Anfragen sehr gut verarbeiten. Warum also? Schauen wir uns zunächst ein Bild an
Auf dem obigen Bild können wir sehen, dass der js-Hauptthread einen Ausführungsstapel hat und der gesamte js-Code im Ausführungsstapel ausgeführt wird. Wenn Sie während der Ausführung des Codes auf asynchronen Code stoßen (z. B. setTimeout, Ajax, Promise.then und Benutzerklicks usw.), fügt der Browser diese Codes in einen Thread ein (hier nennen wir ihn „Behind-the“) -Szenen-Thread). Durch Warten wird die Ausführung des Hauptthreads nicht blockiert Wenn auf die Anfrage geantwortet wird, wird sie vom Thread verarbeitet. Die Rückruffunktion wird in die Aufgabenwarteschlange gestellt und wartet auf die Ausführung. Wenn der Hauptthread mit der Ausführung des gesamten Codes im Stapel fertig ist, prüft er, ob eine auszuführende Aufgabe in der Aufgabenwarteschlange vorhanden ist. Wenn eine auszuführende Aufgabe vorhanden ist, wird die Aufgabe gestellt zur Ausführung in den Ausführungsstapel. Wenn die aktuelle Aufgabenwarteschlange leer ist, wartet sie in einer Schleife weiter auf das Eintreffen der Aufgabe. Daher wird dies als Ereignisschleife bezeichnet.
Hier kommt also die Frage. Welche Aufgabe sollte zuerst ausgeführt werden, wenn sich viele Aufgaben in der Aufgabenwarteschlange befinden?
Tatsächlich (wie im Bild oben gezeigt) verfügt js über zwei Aufgabenwarteschlangen, eine heißt Makrotask-Warteschlange (Aufgabenwarteschlange) und die andere heißt Mikrotask-Warteschlange
Ersteres wird hauptsächlich für relativ umfangreiche Arbeiten verwendet. Zu den häufigsten gehören setTimeout, setInterval, Benutzerinteraktionsvorgänge, UI-Rendering usw.
Letzteres wird hauptsächlich für relativ kleine Arbeiten verwendet, was häufig vorkommt. Es gibt Promise, process.nextTick (nodejs)
Was sind also die spezifischen Unterschiede zwischen den beiden? , wenn zwei Aufgaben gleichzeitig erscheinen, welche sollte ausgewählt werden?
Tatsächlich macht die Ereignisschleife Folgendes:
Überprüfen Sie, ob die Makrotask-Warteschlange leer ist . Wenn nicht, fahren Sie mit dem nächsten Schritt fort, springen Sie zu 3
Nehmen Sie die erste Aufgabe aus der Makrotask-Warteschlange (mit der längsten Zeit in der Warteschlange) und führen Sie sie aus im Ausführungsstapel (nur einer). Fahren Sie nach der Ausführung mit dem nächsten Schritt fort
Überprüfen Sie, ob die Microtask-Warteschlange leer ist. Wenn nicht, fahren Sie mit dem nächsten Schritt fort, andernfalls springen Sie zu 1 (eine neue Ereignisschleife starten)
Aus der Mikrotask-Warteschlange abrufen Die Aufgabe an der Spitze der Warteschlange (mit der längsten Zeit in der Warteschlange) wird zur Ausführung in die Ereigniswarteschlange gestellt. Springt nach der Ausführung zu 3
Unter anderem wird die während der Ausführung des Codes hinzugefügte Mikrotask-Aufgabe im aktuellen Ereignisschleifenzeitraum ausgeführt und die neu hinzugefügte Eine Makrotask-Aufgabe kann nur warten, bis die nächste Ereignisschleife ausgeführt wird (eine Ereignisschleife führt nur eine Makrotask aus).
Schauen wir uns zunächst einen Code an.
console.log(1) setTimeout(function() { //settimeout1 console.log(2) }, 0); const intervalId = setInterval(function() { //setinterval1 console.log(3) }, 0) setTimeout(function() { //settimeout2 console.log(10) new Promise(function(resolve) { //promise1 console.log(11) resolve() }) .then(function() { console.log(12) }) .then(function() { console.log(13) clearInterval(intervalId) }) }, 0); //promise2 Promise.resolve() .then(function() { console.log(7) }) .then(function() { console.log(8) }) console.log(9)
Was sollte Ihrer Meinung nach das Ergebnis sein? ?
Die Ergebnisse, die ich in der Knotenumgebung und der Chrome-Konsole ausgebe, sind wie folgt:
1 9 7 8 2 3 10 11 12 13
Im obigen Beispiel
die erste Ereignisschleife:
console.log(1) wird ausgeführt, Ausgabe 1
settimeout1 wird ausgeführt und zur Makrotask-Warteschlange hinzugefügt
-
setinterval1 wird ausgeführt und zur Makrotask-Warteschlange hinzugefügt
settimeout2 wird ausgeführt und zur Makrotask-Warteschlange hinzugefügt
promise2 wird ausgeführt und seine zwei Die Funktion then wird zur Mikrotask-Warteschlange hinzugefügt
console.log(9) wird ausgeführt und die Ausgabe ist 9
Gemäß Die Definition der Ereignisschleife wird als nächstes ausgeführt. Die hinzugefügten Mikrotask-Aufgaben werden in der Reihenfolge ihres Eintritts in die Warteschlange ausgeführt. Console.log(7) und console.log(8) werden ausgegeben Die Warteschlange ist leer. Gehen Sie zurück zum ersten Schritt und betreten Sie die nächste Ereignisschleife. Zu diesem Zeitpunkt lautet die Makrotask-Warteschlange: settimeout1, setinterval1, settimeout2
Die zweite Ereignisschleife :
- aus der Makrotask-Warteschlange Holen Sie sich die Aufgabe an der Spitze des Teams (settimeout1) und führen Sie sie aus.
Die Mikrotask-Warteschlange ist leer Der erste Schritt und die nächste Ereignisschleife. Zu diesem Zeitpunkt lautet die Makrotask-Warteschlange: setinterval1, settimeout2
Die dritte Ereignisschleife:
- Nehmen Sie die Aufgabe an der Spitze des Teams (setinterval1) aus der Makrotask-Warteschlange und führen Sie sie aus, geben Sie 3 aus und fügen Sie dann das neu generierte setinterval1 zur Makrotask-Warteschlange hinzu
Die Mikrotask-Warteschlange ist leer. Kehren Sie zum ersten Schritt zurück und betreten Sie die nächste Ereignisschleife. Zu diesem Zeitpunkt lautet die Makrotask-Warteschlange: settimeout2, setinterval1
Die vierte Ereignisschleife:
- Nehmen Sie die Aufgabe an der Spitze des Teams (settimeout2) aus der Makrotask-Warteschlange, führen Sie sie aus, geben Sie 10 aus und führen Sie die Funktion in New Promise aus (Die Funktion in New Promise ist eine synchrone Operation. keine asynchrone Operation), geben Sie 11 aus und fügen Sie die beiden Then-Funktionen zur Mikrotask-Warteschlange hinzu
Nehmen Sie aus der Mikrotask-Warteschlange die Aufgabe an der Spitze der Warteschlange und führen Sie sie aus, bis sie leer ist. Daher werden die beiden neu hinzugefügten Mikrotask-Aufgaben nacheinander ausgeführt, 12 und 13 ausgegeben und setinterval1 gelöscht.
Zu diesem Zeitpunkt sind sowohl die Mikrotask-Warteschlange als auch die Makrotask-Warteschlange leer, und der Browser prüft immer, ob die Warteschlange leer ist leer und auf neue warten Die Aufgabe wird zur Warteschlange hinzugefügt.
Hier fragen Sie sich vielleicht, warum in der ersten Schleife die Makroaufgabe nicht zuerst ausgeführt wird? Denn sollten wir je nach Prozess nicht zuerst prüfen, ob die Makrotask-Warteschlange leer ist, und dann die Mikrotask-Warteschlange überprüfen?
Grund: Da es sich bei der Aufgabe, die zu Beginn im js-Hauptthread ausgeführt wird, um eine Makrotask-Aufgabe handelt, wird gemäß dem Prozess der Ereignisschleife nur eine Makrotask-Aufgabe in einer Ereignisschleife ausgeführt Im Hauptthread wird die erste Aufgabe aus der Mikrotask-Warteschlange entnommen und ausgeführt.
Hinweis:
Wenn eine Mikrotask-Aufgabe ausgeführt wird, tritt sie nur dann in die nächste Ereignisschleife ein, wenn die Mikrotask-Warteschlange leer ist Mikrotask-Aufgaben führen dazu, dass der Hauptthread Mikrotask-Aufgaben ausführt, und es gibt keine Möglichkeit, Makrotask-Aufgaben auszuführen. Auf diese Weise können wir keine UI-Rendering-/IO-Operationen/Ajax-Anfragen ausführen . geschehen. In „process.nexttick“ in nodejs können Sie die maximale Anzahl von Aufrufen festlegen, um ein Blockieren des Hauptthreads zu verhindern.
Damit führen wir ein neues Problem ein, das Timer-Problem. Ist der Timer echt und zuverlässig? Wenn ich beispielsweise einen Befehl ausführe: setTimeout(task, 100), wird er dann genau nach 100 Millisekunden ausgeführt? Tatsächlich können wir aufgrund der obigen Diskussion wissen, dass dies unmöglich ist.
Ich denke, jeder sollte den Grund kennen, denn nachdem Sie setTimeout(task,100) ausgeführt haben, stellen Sie eigentlich nur sicher, dass die Aufgabe nach 100 Millisekunden in die Makrotask-Warteschlange gelangt, aber das bedeutet vielleicht nicht, dass sie sofort ausgeführt werden kann Der Hauptthread führt derzeit einen zeitaufwändigen Vorgang aus, oder es befinden sich möglicherweise viele Aufgaben in der Mikrotask-Warteschlange. Dies kann der Grund sein, warum alle setTimeout kritisiert haben.
Das Obige ist nur meine persönliche Meinung der Event-Schleife. Einige Meinungen und Referenzen aus anderen hervorragenden Artikeln
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung von Beispielen für die js-Ereignisschleife. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

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



JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

Wenn der Lambda-Ausdruck aus der Schleife ausbricht, sind spezifische Codebeispiele erforderlich. Bei der Programmierung ist die Schleifenstruktur eine wichtige Syntax, die häufig verwendet wird. Unter bestimmten Umständen möchten wir jedoch möglicherweise aus der gesamten Schleife ausbrechen, wenn eine bestimmte Bedingung im Schleifenkörper erfüllt ist, anstatt nur die aktuelle Schleifeniteration zu beenden. Zu diesem Zeitpunkt können uns die Eigenschaften von Lambda-Ausdrücken dabei helfen, das Ziel zu erreichen, aus der Schleife zu springen. Der Lambda-Ausdruck ist eine Möglichkeit, eine anonyme Funktion zu deklarieren, die intern einfache Funktionslogik definieren kann. Es unterscheidet sich von einer gewöhnlichen Funktionsdeklaration:

jQuery ist eine beliebte JavaScript-Bibliothek, die zur Vereinfachung der DOM-Manipulation, Ereignisbehandlung, Animationseffekte usw. verwendet werden kann. Bei der Webentwicklung stoßen wir häufig auf Situationen, in denen wir die Ereignisbindung für ausgewählte Elemente ändern müssen. In diesem Artikel wird erläutert, wie Sie mit jQuery ausgewählte Elementänderungsereignisse binden, und es werden spezifische Codebeispiele bereitgestellt. Zuerst müssen wir ein Dropdown-Menü mit Optionen erstellen, die Beschriftungen verwenden:

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert

Zu den Methoden zum Erstellen ereignisbasierter Anwendungen in PHP gehört die Verwendung der EventSourceAPI zum Erstellen einer Ereignisquelle und die Verwendung des EventSource-Objekts zum Abhören von Ereignissen auf der Clientseite. Senden Sie Ereignisse mithilfe von Server Sent Events (SSE) und warten Sie auf der Clientseite mithilfe eines XMLHttpRequest-Objekts auf Ereignisse. Ein praktisches Beispiel ist die Verwendung von EventSource zur Aktualisierung der Bestandszahlen in Echtzeit auf einer E-Commerce-Website. Dies wird auf der Serverseite durch zufälliges Ändern des Bestands und Senden von Aktualisierungen erreicht, und der Client wartet über EventSource auf Bestandsaktualisierungen und zeigt diese an Echtzeit.

Iterator-Schnittstelle Die Iterator-Schnittstelle ist eine Schnittstelle zum Durchlaufen von Sammlungen. Es bietet mehrere Methoden, darunter hasNext(), next() und remove(). Die Methode hasNext() gibt einen booleschen Wert zurück, der angibt, ob es ein nächstes Element in der Sammlung gibt. Die Methode next() gibt das nächste Element in der Sammlung zurück und entfernt es aus der Sammlung. Die Methode „remove()“ entfernt das aktuelle Element aus der Sammlung. Das folgende Codebeispiel zeigt, wie die Iterator-Schnittstelle zum Durchlaufen einer Sammlung verwendet wird: Listnames=Arrays.asList("John","Mary","Bob");Iterator

Ersetzen rekursiver Aufrufe in Java-Funktionen durch Iteration. In Java ist die Rekursion ein leistungsstarkes Werkzeug zur Lösung verschiedener Probleme. In einigen Fällen kann die Verwendung von Iteration jedoch eine bessere Option sein, da sie effizienter und weniger anfällig für Stapelüberläufe ist. Hier sind die Vorteile der Iteration: Effizienter, da nicht für jeden rekursiven Aufruf ein neuer Stapelrahmen erstellt werden muss. Es ist weniger wahrscheinlich, dass Stapelüberläufe auftreten, da die Stapelplatznutzung begrenzt ist. Iterative Methoden als Alternative zu rekursiven Aufrufen: In Java gibt es mehrere Methoden, um rekursive Funktionen in iterative Funktionen umzuwandeln. 1. Verwenden Sie den Stapel. Die Verwendung des Stapels ist die einfachste Möglichkeit, eine rekursive Funktion in eine iterative Funktion umzuwandeln. Der Stapel ist eine Last-In-First-Out-Datenstruktur (LIFO), ähnlich einem Funktionsaufrufstapel. publicintfa

In diesem Artikel wird ausführlich erläutert, wie PHP alle Werte eines Arrays zurückgibt, um ein Array zu bilden. Der Herausgeber hält dies für recht praktisch, daher teile ich es Ihnen als Referenz mit und hoffe, dass Sie nach dem Lesen dieses Artikels etwas gewinnen können . Verwenden der Funktion array_values() Die Funktion array_values() gibt ein Array aller Werte in einem Array zurück. Die Schlüssel des ursprünglichen Arrays bleiben nicht erhalten. $array=["foo"=>"bar","baz"=>"qux"];$values=array_values($array);//$values werden ["bar","qux"]Verwendet Eine Schleife kann eine Schleife verwenden, um alle Werte des Arrays manuell abzurufen und zu einem neuen hinzuzufügen
