Heim > Artikel > Web-Frontend > Detaillierte Einführung in den JS-Thread-Mechanismus und den Ereignismechanismus (Bild und Text)
Der Inhalt dieses Artikels ist eine detaillierte Einführung (Bilder und Texte) über den js-Thread-Mechanismus und den Ereignismechanismus. Ich hoffe, dass er hilfreich ist du hilfst.
1. Prozesse und Threads
1Ein Prozess bezieht sich auf die Ausführung eines Programms, das einen eindeutigen Speicherplatz belegt. Sie können den Prozess über den Windows Task-Manager
anzeigen (wie unten gezeigt). Gleichzeitig ermöglicht dasselbe Computersystem den parallelen Zustand von zwei oder mehr Prozessen, was einem Multiprozess entspricht. Auf einem Computer können beispielsweise WeChat, QQ und verschiedene Browser gleichzeitig ausgeführt werden.Einige Browser werden in einem einzigen Prozess ausgeführt, z. B. Firefox und die alte Version von IE, und andere werden in mehreren Prozessen ausgeführt, z. B. Chrome und die neue Version von IE.
2. Threads
Einige Prozesse können mehr als eine Sache gleichzeitig ausführen, z. B. Word, Dinge wie Tippen, Rechtschreibprüfung, Drucken und mehr können gleichzeitig erledigt werden. Wenn Sie innerhalb eines Prozesses mehrere Dinge gleichzeitig erledigen möchten, müssen Sie mehrere „Unteraufgaben“ gleichzeitig ausführen. Wir nennen diese „Unteraufgaben“ innerhalb der Prozess-Threads. Thread bezieht sich auf die grundlegende Planungseinheit der CPU, einen vollständigen Prozess der Programmausführung und eine unabhängige Ausführungseinheit innerhalb des Prozesses. Unter Multithreading versteht man die gleichzeitige Ausführung mehrerer Threads innerhalb eines Prozesses.
Der Browser läuft multithreaded. Beispielsweise können Sie mit einem Browser gleichzeitig Songs herunterladen, anhören und Videos ansehen. Darüber hinaus müssen wir wissen, dass ein Hauptmerkmal der JavaScript-Sprache Single-Threading ist Um die Rechenleistung von Multi-Core-CPUs zu nutzen, HTML5 schlägt den Web Worker-Standard vor , was es JavaScript-Skripten ermöglicht, mehrere Threads zu erstellen, aber untergeordnete Threads unterliegen vollständig den Haupt-Thread-Steuerelementen und dürfen das DOM nicht manipulieren. Daher ändert dieser neue Standard nichts an der Single-Threaded-Natur von JavaScript.
Da jeder Prozess mindestens eine Sache tun muss, hat ein Prozess mindestens einen Thread. Natürlich kann ein komplexer Prozess wie Word mehrere Threads haben und mehrere Threads können gleichzeitig ausgeführt werden. Die Ausführungsmethode des Multithreadings ist dieselbe wie bei mehreren Prozessen. Das Betriebssystem wechselt auch schnell zwischen mehreren Threads. Ermöglichen, dass jeder Thread abwechselnd kurz ausgeführt wird und scheinbar gleichzeitig ausgeführt wird. Um tatsächlich mehrere Threads gleichzeitig ausführen zu können, ist natürlich eine Multi-Core-CPU erforderlich.
3. Prozesse und Threads Die Anwendung muss in einem Thread eines bestimmten Prozesses ausgeführt werdenNachteile von Single Thread
: Geringe EffizienzVorteile von Multi-Threading
: Kann die CPU-Auslastung effektiv verbessernNachteile von Multi-Threading
:Aufwand beim Erstellen von Multi-Threading Threads
Sehen wir uns zunächst ein Beispiel an, um zu sehen, ob der Timer dies tut Sicherstellen, dass nach 200 ms ausgeführt wird?
document.getElementById('btn').onclick = function () { var start = Date.now() console.log('启动定时器前...') setTimeout(function () { console.log('定时器执行了', Date.now() - start) }, 200) console.log('启动定时器后...') // 做一个长时间的工作 for (var i = 0; i <p style="text-align: center;"><span class="img-wrap"><img src="https://img.php.cn//upload/image/139/417/140/1539669885863938.png" title="1539669885863938.png" alt="Detaillierte Einführung in den JS-Thread-Mechanismus und den Ereignismechanismus (Bild und Text)"></span><br>Tatsächlich wird der Timer erst ausgeführt, wenn 625 ms vergangen sind. Der Timer garantiert keine Echtzeitausführung. Er verzögert sich normalerweise etwas oder kann lange dauern (wie im obigen Beispiel). </p><p><strong>2 In separaten Threads ausgeführt? </strong></p><p><strong>Die Timer-Callback-Funktion wird im Hauptthread ausgeführt</strong> Die spezifische Implementierungsmethode wird unten vorgestellt. </p><p><strong>4. Browser-Ereignisschleifenmodell (Polling) </strong></p><p><strong>Warum JavaScript Single-Threaded ist</strong></p><p><strong> Ein Hauptmerkmal der JavaScript-Sprache ist Single-Threading, was bedeutet, dass sie jeweils nur eine Sache ausführen kann</strong>. Warum kann JavaScript also nicht mehrere Threads haben? Dadurch kann die Effizienz verbessert werden. </p><p>Der einzelne Thread von JavaScript hängt mit seinem Zweck zusammen. Als Browser-Skriptsprache besteht der Hauptzweck von JavaScript darin, mit Benutzern zu interagieren und das DOM zu manipulieren. Dies legt fest, dass es nur Single-Threaded sein kann, da es sonst zu sehr komplexen Synchronisationsproblemen kommt. Angenommen, JavaScript verfügt über zwei Threads gleichzeitig. Ein Thread fügt Inhalt zu einem bestimmten DOM-Knoten hinzu und der andere Thread löscht den Knoten. Welchen Thread sollte der Browser in diesem Fall verwenden? </p><p>Um Komplexität zu vermeiden, ist JavaScript seit seiner Geburt Single-Threaded. Dies ist zum Kernmerkmal dieser Sprache geworden und wird sich auch in Zukunft nicht ändern. <br>Um die Rechenleistung von Multi-Core-CPUs zu nutzen, <strong>HTML5 schlägt den Web Worker-Standard vor, der es JavaScript-Skripten ermöglicht, mehrere Threads zu erstellen, die untergeordneten Threads werden jedoch vollständig vom Haupt-Thread gesteuert und müssen dies auch tun Betreiben Sie das DOM nicht</strong>. Daher ändert dieser neue Standard nichts an der Single-Threaded-Natur von JavaScript. </p><p><strong>2.Ereignisschleife</strong></p><p>Alle Aufgaben in JavaScript können in zwei Typen unterteilt werden, einer ist eine synchrone Aufgabe und der andere eine asynchrone Aufgabe (z. B. verschiedene Browserereignisse, Timer und Ajax usw.). <strong>Synchronische Aufgaben beziehen sich auf Aufgaben, die zur Ausführung im Hauptthread in die Warteschlange gestellt werden. Die nächste Aufgabe kann erst ausgeführt werden, nachdem die vorherige Aufgabe ausgeführt wurde. Asynchrone Aufgaben beziehen sich auf Aufgaben, die nicht in den Hauptthread, sondern in die „Aufgabenwarteschlange“ gelangen. Nur wenn die „Aufgabenwarteschlange“ den Hauptthread benachrichtigt, dass eine asynchrone Aufgabe ausgeführt werden kann, gelangt die Aufgabe zur Ausführung in den Hauptthread </strong>. </p><p>Im Einzelnen ist der Betriebsmechanismus der asynchronen Ausführung wie folgt. (Dasselbe gilt für die synchrone Ausführung, da sie als asynchrone Ausführung ohne asynchrone Aufgaben betrachtet werden kann.) </p><p> (1) Alle synchronen Aufgaben werden im Hauptthread ausgeführt und bilden einen Ausführungskontextstapel. </p><p> (2) Zusätzlich zum Hauptthread gibt es auch eine „Aufgabenwarteschlange“. Solange die asynchrone Aufgabe laufende Ergebnisse hat, wird ein Ereignis in die „Aufgabenwarteschlange“ gestellt. </p><p> (3) Sobald alle Synchronisierungsaufgaben im „Ausführungsstapel“ abgeschlossen sind, liest das System die „Aufgabenwarteschlange“, um zu sehen, welche Ereignisse darin enthalten sind. Diese entsprechenden asynchronen Aufgaben beenden den Wartezustand, betreten den Ausführungsstapel und beginnen mit der Ausführung. </p><p> (4) Der Hauptthread wiederholt den dritten Schritt oben </p><p><strong>Der Hauptthread liest Ereignisse aus der „Aufgabenwarteschlange“, sodass der gesamte Vorgang ausgeführt wird Mechanismus wird auch Ereignisschleife genannt </strong></p><p style="max-width:90%"><span class="img-wrap"><img src="https://img.php.cn//upload/image/280/170/433/1539669867171806.png" title="1539669867171806.png" alt="Detaillierte Einführung in den JS-Thread-Mechanismus und den Ereignismechanismus (Bild und Text)"></span><br>Das folgende Beispiel veranschaulicht die Ereignisschleife gut: </p><pre class="brush:php;toolbar:false"> setTimeout(function () { console.log('timeout 2222') alert('22222222') }, 2000) setTimeout(function () { console.log('timeout 1111') alert('1111111') }, 1000) setTimeout(function () { console.log('timeout() 00000') }, 0)//当指定的值小于 4 毫秒,则增加到 4ms(4ms 是 HTML5 标准指定的,对于 2010 年及之前的浏览器则是 10ms) function fn() { console.log('fn()') } fn() console.log('alert()之前') alert('------') //暂停当前主线程的执行, 同时暂停计时, 点击确定后, 恢复程序执行和计时 console.log('alert()之后')
Es gibt zwei Punkte, auf die wir achten müssen:
Timer-Nullverzögerung (setTimeout(func, 0)) bedeutet nicht, dass die Rückruffunktion ausgeführt wird sofort. Die Callback-Funktion wird erst nach mindestens 4 ms ausgeführt. Es hängt davon ab, ob der Hauptthread gerade inaktiv ist und welche Aufgaben davor in der „Aufgabenwarteschlange“ warten.
Erst wenn die angegebene Zeit erreicht ist, fügt der Timer die entsprechende Rückruffunktion in das Ende der „Aufgabenwarteschlange“ ein
Zusammenfassung: Asynchrone Aufgaben (verschiedene Browserereignisse, Timer, Ajax usw.) werden zuerst zur „Aufgabenwarteschlange“ hinzugefügt (wenn der Timer seine angegebenen Parameter erreicht). Wenn der Stapelstapel (JavaScript-Hauptthread) leer ist, wird die erste Aufgabe (Warteschlangenkopf) der Warteschlangenwarteschlange (Aufgabenwarteschlange) gelesen und schließlich ausgeführt.
5. H5 Web Worker (Multi-Threading)
1. Die Rolle von Web Workern
Wie oben erwähnt , JavaScript ist Single-Threaded. Wenn eine Seite eine JS-Datei mit komplexen Vorgängen lädt, kann es sein, dass die Benutzeroberfläche kurzzeitig „einfriert“ und keine anderen Vorgänge ausgeführt werden können. Zum Beispiel das folgende Beispiel:
<input> <button>计算</button> <script> // 1 1 2 3 5 8 f(n) = f(n-1) + f(n-2) function fibonacci(n) { return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2) //递归调用 } var input = document.getElementById('number') document.getElementById('btn').onclick = function () { var number = input.value var result = fibonacci(number) alert(result) } </script>
很显然遇到这种页面堵塞情况,很影响用户体验的,有没有啥办法可以改进这种情形?----Web Worker就应运而生了!
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。其原理图如下:
主线程
首先主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程
var worker = new Worker('work.js');
然后主线程调用worker.postMessage()方法,向 Worker 发消息。
接着,主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。
var input = document.getElementById('number') document.getElementById('btn').onclick = function () { var number = input.value //创建一个Worker对象 var worker = new Worker('worker.js') // 绑定接收消息的监听 worker.onmessage = function (event) { console.log('主线程接收分线程返回的数据: '+event.data) alert(event.data) } // 向分线程发送消息 worker.postMessage(number) console.log('主线程向分线程发送数据: '+number) } console.log(this) // window
Worker 线程
Worker 线程内部需要有一个监听函数,监听message事件。
通过 postMessage(data) 方法来向主线程发送数据。
//worker.js文件 function fibonacci(n) { return n<p>这样当分线程在计算时,用户界面还可以操作,而且更早拿到计算后数据,响应速度更快了。</p><p style="text-align: center;"><img src="https://img.php.cn//upload/image/673/101/817/1539670027106347.gif" title="1539670027106347.gif" alt="Detaillierte Einführung in den JS-Thread-Mechanismus und den Ereignismechanismus (Bild und Text)"><span class="img-wrap"></span></p><p><strong>3. Web Workers的缺点</strong></p>
不能跨域加载JS
worker内代码不能访问DOM(更新UI)
不是每个浏览器都支持这个新特性(本文例子只能在Firefox浏览器上运行,chrome不支持)
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in den JS-Thread-Mechanismus und den Ereignismechanismus (Bild und Text). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!