Vor zwei Tagen habe ich einen Artikel mit der Einführung „Wie implementiere ich ein rechtzeitiges setTimeout?“ gesehen. 》, der Artikel entstand aus einer Interviewfrage: Gibt es eine Möglichkeit, setTimeout rechtzeitig festzulegen? Weitere Einzelheiten entnehmen Sie bitte Anhang [1]. Nachdem ich ihn gelesen hatte, interessierte ich mich für die Funktion setTimeout und überprüfte die entsprechenden Dokumente auf MDN noch einmal. Darin wurde erwähnt, dass [minimale Verzögerung >= 4 ms], sodass ein 0-ms-Verzögerungstimer nicht mit setTimeout implementiert werden kann. Wenn Sie es implementieren möchten, finden Sie einen Referenzlink [2]. Die Implementierungsidee des Autors besteht darin, es durch postMessage zu simulieren, die Beschränkung von setTimeout zu umgehen und so einen 0-ms-Verzögerungstimer zu implementieren. Kurz gesagt geht es darum, eine Makroaufgabe zu starten, um den Rückruf auszuführen. Sehen wir uns an, wie es implementiert wird: (Funktion() { var Zeitüberschreitungen = []; var Nachrichtenname = "Null-Timeout-Nachricht"; // Wie setTimeout, nimmt aber nur ein Funktionsargument an. Es gibt // kein Zeitargument (immer Null) und keine Argumente (Sie müssen einen Abschluss verwenden) Funktion setZeroTimeout(fn) { Zeitüberschreitungen.push(fn); window.postMessage(Nachrichtenname, "*"); } Funktion handleMessage(Ereignis) { wenn (Ereignisquelle == Fenster und Ereignisdaten == Nachrichtenname) { event.stopPropagation(); wenn (Timeouts.Länge > 0) { var fn = timeouts.shift(); fn(); } } } window.addEventListener("Nachricht", handleMessage, true); // Fügen Sie das eine Element hinzu, das wir dem Fensterobjekt hinzufügen möchten. Fenster.setZeroTimeout = setZeroTimeout; })(); Der Autor stellt auch eine Demo-Seite zur Verfügung [3]. Ein Vergleich mit setTimeout(0) ergibt folgendes Ausführungsergebnis in meinem Browser:
Den Vergleichsergebnissen zufolge wird setZeroTimeout hundertmal schneller ausgeführt als setTimeout, was eine enorme Verbesserung darstellt. Was ich heute besprechen möchte, ist, welche anderen Möglichkeiten es gibt, zusätzlich zur obigen Methode einen 0-ms-Verzögerungstimer zu implementieren. Erstens müssen wir sicherstellen, dass unser benutzerdefinierter Timer asynchron ist, und zweitens, dass er so früh wie möglich ausgeführt wird. Apropos Asynchronität: js bietet mehrere Lösungen, die wir nacheinander überprüfen können. Bevor wir die verschiedenen Implementierungsmethoden im Detail besprechen, sehen wir uns die von der Vereinbarung bereitgestellte setTimeout-Vergleichsversion wie folgt an. Die Ausführungszeit der benutzerdefinierten Implementierungsschemata wird mit der setTimeout-Version verglichen. Der Code ist relativ einfach: (Funktion() { sei i = 0; const start = Date.now(); Funktion test() { wenn(i++ < 100) { setzeTimeout(test); } anders { console.log('setTimeout-Ausführungszeit:', Date.now() - Start); } } setzeTimeout(test); })(); WarteschlangeMikrotaskDie queueMicrotask-API kann eine Mikrotask hinzufügen. Sie ist relativ einfach zu verwenden. Übergeben Sie einfach eine Rückruffunktion. Die konkrete Implementierung ist wie folgt: (Funktion() { Funktion setZeroTimeout(fn) { WarteschlangeMicrotask(fn); } sei i = 0; const start = Date.now(); Funktion test() { wenn(i++ < 100) { setZeroTimeout(test); } anders { console.log('setZeroTimeout-Ausführungszeit:', Date.now() - Start); } } setZeroTimeout(test); })(); Durch den Vergleich mit der setTimeout-Version sieht das Endergebnis wie folgt aus:
Auf MDN gibt es eine ausführliche Einführung zu dieser API, daher werde ich hier nicht näher darauf eingehen. Laut Spezifikationsdokument wird in den meisten Fällen empfohlen, APIs wie requestAnimationFrame() und requestIdleCallback() zu verwenden, da queueMicrotask das Rendering blockiert, was in vielen Fällen keine gute Praxis ist. asynchron/wartenAsync/await ist für Front-End-Entwickler bereits unverzichtbar und wir können es auch hier verwenden, um Folgendes zu erreichen: (Funktion() { asynchrone Funktion setAsyncTimeout(fn) { Versprechen.lösen().dann(fn); } sei i = 0; const start = Date.now(); asynchroner Funktionstest () { wenn (i++ < 100) { warte auf setAsyncTimeout(Test); } anders { console.log('setAsyncTimeout-Ausführungszeit:', Date.now() - Start); } } setAsyncTimeout(test); })(); Durch den Vergleich mit der setTimeout-Version sieht das Endergebnis wie folgt aus:
Wenn Ihnen der Aufwand nichts ausmacht, können Sie auch Promise zur Implementierung verwenden. Tatsächlich sind sie alle ähnlich, nur ein wenig mehr Code, der hier weggelassen wird. NachrichtenkanalMessageChannel ermöglicht uns, einen neuen Nachrichtenkanal zu erstellen und Daten über seine beiden MessagePort-Eigenschaften zu senden. MessageChannel bietet das Konzept von Ports, um die Kommunikation zwischen Ports zu erreichen, z. B. die Kommunikation zwischen Workern/iFrames. (Funktion() { const channel = neuer Nachrichtenkanal(); Funktion setzeMessageChannelTimeout(fn) { channel.port2.postMessage(null); } channel.port1.onmessage = Funktion() { prüfen(); }; sei i = 0; const start = Date.now(); Funktion test() { wenn(i++ < 100) { setzeMessageChannelTimeout(test); } anders { console.log('setMessageChannelTimeout Ausführungszeit:', Date.now() - Start); } } setzeMessageChannelTimeout(test); })(); Durch den Vergleich mit der setTimeout-Version sieht das Endergebnis wie folgt aus:
Die Ausführung der dritten Methode dauert länger als die beiden vorherigen, da der MessageChannel Makrotasks generiert, während die anderen beiden Methoden Mikrotasks sind. Mikrotasks werden zuerst ausgeführt und blockieren den Hauptthread, sodass sie länger dauern. endlich Dieser Artikel bietet drei Implementierungsmethoden, die alle auf der von js bereitgestellten asynchronen Lösung basieren. Die Implementierung selbst ist nicht kompliziert. Anhang 【1】https://mp.weixin.qq.com/s/QRIXBoKr2dMgLob3Atq9-g Damit ist dieser Artikel über verschiedene Möglichkeiten zur Implementierung eines 0-ms-Verzögerungstimers in js abgeschlossen. Weitere relevante Inhalte zum js-Verzögerungstimer finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Detaillierte Anweisungen zur Installation von SuPHP auf CentOS 7.2
>>: Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.16 unter macOS
Inhaltsverzeichnis 1. Installieren Sie das psutil...
Dieser Artikel beschreibt, wie man über Docker ei...
Die Tags <abbr> und <acronym> stellen ...
Szenario 1. Pflegen Sie ein Bürgersystem mit eine...
Hintergrund Indizes sind ein zweischneidiges Schw...
In diesem Artikel werden die Installations- und K...
Prozessstrukturdiagramm Nginx ist eine Multiproze...
Inhaltsverzeichnis Installieren: 1. Grundlegende ...
Inhaltsverzeichnis 1. Arithmetische Operatoren 2....
Was ist JDK? Nun, wenn Sie diese Frage nicht kenn...
Inhaltsverzeichnis brauchen: Wichtige Punkte: Anh...
1. Laden Sie das MySQL-Installationspaket herunte...
Ergebnisse erzielen Implementierungscode html <...
Inhaltsverzeichnis Hintergrund dieser Serie Überb...
1: Installieren Sie MongoDB im Docker Schritt 1: ...