Heim Web-Frontend js-Tutorial Eine ausführliche Erklärung des JavaScript-Timing-Mechanismus (einschließlich Code)

Eine ausführliche Erklärung des JavaScript-Timing-Mechanismus (einschließlich Code)

May 19, 2018 pm 02:51 PM
javascript js 机制

Dieser Artikel führt hauptsächlich ein tiefgreifendes Verständnis des JavaScript-Timing-Mechanismus ein, der für das Erlernen von JavaScript hilfreich ist. Interessierte Freunde können sich darauf beziehen.

In diesem Artikel wird der JavaScript-Timing-Mechanismus vorgestellt. Um den Timing-Mechanismus von JavaScript zu verstehen, müssen Sie den Ausführungsmechanismus von JavaScript kennen.

Zuallererst ist JavaScript ereignisgesteuert, indem es in einem einzelnen Thread (JavaScript-Engine-Thread) ausgeführt wird.

1. Es gibt mehrere Threads im Browser

Die grundlegendsten Threads, die in einem Browser enthalten sind:

1.

2. Timer-Thread, setInterval und setTimeout lösen diesen Thread aus.

3. Browser-Ereignis-Trigger-Thread, dieser Thread löst Onclick-, Onmousemove- und andere Browser-Events aus.

4. Der Interface-Rendering-Thread ist für das Rendern der HTML-Elemente der Browser-Oberfläche verantwortlich. Hinweis: Während die JavaScript-Engine das Skript ausführt, befindet sich der Schnittstellen-Rendering-Thread in einem angehaltenen Zustand. Das heißt, wenn JavaScript zum Betreiben von Knoten in der Schnittstelle verwendet wird, wird dies nicht sofort widergespiegelt, bis der JavaScript-Engine-Thread inaktiv ist. (Dies ist der letzte)

5. HTTP-Anfragethread (Ajax-Anfragen gehören auch dazu).

Die oben genannten Threads arbeiten zusammen, um die Arbeit unter der Kontrolle des Browserkernels abzuschließen (ich kenne die Details nicht).

2. Aufgabenwarteschlange

Wir wissen, dass JavaScript Single-Threaded ist und der gesamte JavaScript-Code im JavaScript-Engine-Thread ausgeführt wird. Der Artikel von Lehrer Ruan Yifeng nennt diesen Thread den Hauptthread, bei dem es sich um einen Ausführungsstapel handelt. (Der folgende Inhalt basiert hauptsächlich auf dem Verständnis und der Zusammenfassung des Artikels von Lehrer Ruan Yifeng.)

Wir können diese JavaScript-Codes einzeln als Aufgaben betrachten. Diese Aufgaben sind in synchrone Aufgaben und asynchrone Aufgaben unterteilt. Synchrone Aufgaben (z. B. Variablenzuweisungsanweisungen, Warnanweisungen, Funktionsdeklarationsanweisungen usw.) werden nacheinander direkt im Hauptthread ausgeführt, und asynchrone Aufgaben (z. B. verschiedene Ereignisse, die durch Browser-Ereignistrigger-Threads ausgelöst werden, verwenden von Ajax zurückgegebene Serverantworten usw.) werden in chronologischer Reihenfolge in der Aufgabenwarteschlange (auch Ereigniswarteschlange, Nachrichtenwarteschlange genannt) eingereiht und warten auf ihre Ausführung. Solange die Aufgaben im Hauptthread ausgeführt werden, wird die Aufgabenwarteschlange überprüft, um festzustellen, ob in der Warteschlange Aufgaben warten. Wenn dies der Fall ist, werden die in der Warteschlange befindlichen Aufgaben zur Ausführung in den Hauptthread eingegeben.

Zum Beispiel das folgende Beispiel:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>定时机制</title>

<style type="text/css">
body{
  margin: 0;
  padding: 0;
  position: relative;
  height: 600px;
}

#test{
  height: 30px;
  width: 30px;
  position: absolute;
  left: 0;
  top: 100px;
  background-color: pink;
}
</style>
</head>
<body>
  <p id="test">
  
  </p>

<script>
  var pro = document.getElementById(&#39;test&#39;);
  pro.onclick = function() {
    alert(&#39;我没有立即被执行。&#39;);
  };
  function test() {
    a = new Date();
    var b=0;
   for(var i=0;i<3000000000;i++) {
     b++;
   }
   c = new Date();
   console.log(c-a);
  }

 test();
</script>
</body>
</html>
Nach dem Login kopieren

In diesem Beispiel dauert es etwa 8 bis 9 Sekunden, bis die Funktion test() ausgeführt wird. Wenn wir also diese Seite öffnen, klicken Sie auf Rosa Quadrat vor 8 Sekunden. Das Eingabeaufforderungsfeld wird nicht sofort, sondern nach 8 Sekunden angezeigt. Wenn Sie vor 8 Sekunden mehrmals auf das rosa Feld klicken, wird es nach 8 Sekunden mehrmals angezeigt.

Wenn wir diese Seite öffnen, deklariert der Hauptthread zuerst den Funktionstest, dann die Variable pro, weist dann den p-Knoten pro zu, fügt dann dem p-Knoten ein Klickereignis hinzu und gibt eine Rückruffunktion an (Suspendierung) und rufen Sie dann die Testfunktion auf und führen Sie den darin enthaltenen Code aus. Während der Ausführung des Codes in der Testfunktion haben wir auf den p-Knoten geklickt. Der Browser-Ereignistrigger-Thread hat dieses Ereignis erkannt und das Ereignis in die Aufgabenwarteschlange gestellt, sodass die Aufgabe im Hauptthread (hier der Testfunktion) liegt Abschließend wird dieses Ereignis bei der Überprüfung der Aufgabenwarteschlange gefunden und die entsprechende Callback-Funktion ausgeführt. Wenn wir mehrmals klicken, werden diese mehrfach ausgelösten Ereignisse entsprechend der Auslösezeit in die Aufgabenwarteschlange eingereiht (Sie können ein Klickereignis einem anderen Element hinzufügen und zur Überprüfung abwechselnd auf verschiedene Elemente klicken).

Das Folgende ist eine Zusammenfassung des Ausführungsmechanismus der Aufgabe:

Der Ausführungsmechanismus der asynchronen Ausführung ist wie folgt. (Dasselbe gilt für die synchrone Ausführung, da sie als asynchrone Ausführung ohne asynchrone Aufgaben betrachtet werden kann.)

1. Alle synchronen Aufgaben werden im Hauptthread ausgeführt und bilden einen Ausführungskontextstapel.

2. Zusätzlich zum Hauptthread gibt es auch eine „Aufgabenwarteschlange“. Solange die asynchrone Aufgabe laufende Ergebnisse hat, wird ein Ereignis in die „Aufgabenwarteschlange“ gestellt.

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.

4. Der Hauptthread wiederholt den dritten Schritt oben.

3. Ereignisse und Rückruffunktionen

Wenn wir ein Ereignis für ein DOM-Element angeben, geben wir eine Rückruffunktion an, damit der entsprechende Code ausgeführt werden kann, wenn das Ereignis tatsächlich eintritt.

Die Rückruffunktion des Ereignisses im Hauptthread wird angehalten. Wenn sich ein entsprechendes Ereignis in der Aufgabenwarteschlange befindet, wird die entsprechende Rückruffunktion ausgeführt, wenn der Hauptthread es erkennt. Wir können auch sagen, dass der Hauptthread asynchrone Aufgaben ausführt und die entsprechende Rückruffunktion ausführt.

4. Ereignisschleife

Der Prozess der Überprüfung der Ereignisse in der Aufgabenwarteschlange durch den Hauptthread ist zyklisch, sodass wir ein Diagramm der Ereignisschleife zeichnen können:

上图中主线程产生堆和执行栈,栈中的任务执行完毕后,主线程检查任务队列中由其他线程传入的发生过的事件,检测到排在最前面的事件,就从挂起的回调函数中找出与该事件对应的回调函数,然后在执行栈中执行,这个过程一直重复。

五、定时器

结合以上知识,下面探讨JavaScript中的定时器:setTimeout()和setInterval()。

setTimeout(func, t)是超时调用,间隔一段时间后调用函数。这个过程在事件循环中的过程如下(我的理解):

主线程执行完setTimeout(func, t);语句后,把回调函数func挂起,同时定时器线程开始计时,当计时等于t时,相当于发生了一个事件,这个事件传入任务队列(结束计时,只计时一次),当主线程中的任务执行完后,主线程检查任务队列发现了这个事件,就执行挂起的回调函数func。我们指定的时间间隔t只是参考值,真正的时间间隔取决于执行完setTimeout(func, t);语句后的代码所花费的时间,而且是只大不小。(即使我们把t设为0,也要经历这个过程)。

setInterval(func, t)是间歇调用,每隔一段时间后调用函数。这个过程在事件循环中的过程与上面的类似,但又有所不同。

setTimeout()是经过时间t后定时器线程在任务队列中添加一个事件(注意是一个),而setInterval()是每经过时间t(一直在计时,除非清除间歇调用)后定时器线程在任务队列中添加一个事件,而不管之前添加的事件有没有被主线程检测到并执行。(实际上浏览器是比较智能的,浏览器在处理setInterval的时候,如果发现已任务队列中已经有排队的同一ID的setInterval的间歇调用事件,就直接把新来的事件 Kill 掉。也就是说任务队列中一次只能存在一个来自同一ID的间歇调用的事件。)

举个例子,假如执行完setInterval(func, t);后的代码要花费2t的时间,当2t时间过后,主线程从任务队列中检测到定时器线程传入的第一个间歇调用事件,func开始执行。当第一次的func执行完毕后,第二次的间歇调用事件早已传入任务队列,主线程马上检测到第二次的间歇调用事件,func函数又立即执行。这种情况下func函数的两次执行是连续发生的,中间没有时间间隔。

下面是个例子:

function test() {
    a = new Date();
    var b=0;
   for(var i=0;i<3000000000;i++) {
     b++;
   }
   c = new Date();
   console.log(c-a);
 }
  function test2() {
   var d = new Date().valueOf();
   //var e = d-a;
   console.log(&#39;我被调用的时刻是:&#39;+d+&#39;ms&#39;);
   //alert(1);
  }
  setInterval(test2,3000);
  
 test();
Nach dem Login kopieren

结果:

为什么8.6秒过后没有输出两个一样的时刻,原因在上面的内容中可以找到。

执行例子中的for循环花费了8601ms,在执行for循环的过程中队列中只有一个间歇调用事件在排队(原因如上所述),当8601ms过后,第一个间歇调用事件进入主线程,对于这个例子来说此时任务队列空了,可以再次传入间歇调用事件了,所以1477462632228ms这个时刻第二次间歇调用事件(实际上应该是第三次)传入任务队列,由于主线程的执行栈已经空了,所以主线程立即把对应的回调函数拿来执行,第二次调用与第一次调用之间仅仅间隔了320ms(其实8601+320=8920,差不多就等于9秒了)。我们看到第三次调用已经恢复正常了,因为此时主线程中已经没有其他代码了,只有一个任务,就是隔一段时间执行一次间歇调用的回调函数。

用setTimeout()实现间歇调用的例子:

function test() {
    a = new Date();
    var b=0;
   for(var i=0;i<3000000000;i++) {
     b++;
   }
   c = new Date();
   console.log(c-a);
  }
 
  function test2(){
   var d = new Date().valueOf();
   console.log(&#39;我被调用的时刻是:&#39;+d+&#39;ms&#39;);
   setTimeout(test2,3000);
  }
  setTimeout(test2,3000);
 test();
Nach dem Login kopieren

结果:

每两次调用的时间间隔基本上是相同。想想为什么?

再看一个例子:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flex布局练习</title>

<style type="text/css">
body{
  margin: 0;
  padding: 0;
  position: relative;
  height: 600px;
}

#test{
  height: 30px;
  width: 30px;
  position: absolute;
  left: 0;
  top: 100px;
  background-color: pink;
}
</style>
</head>
<body>
  <p id="test">
  
  </p>

<script>
 var p = document.createElement(&#39;p&#39;);
 p.style.width = &#39;50px&#39;;
 p.style.height = &#39;50px&#39;;
 p.style.border = &#39;1px solid black&#39;;
 
 document.body.appendChild(p);

 alert(&#39;ok&#39;);
 
</script>
</body>
</html>
Nach dem Login kopieren

这个例子的结果是提示框先弹出,然后黑色边框的p元素才出现在页面中。原因很简单,就一句话:

在JavaScript引擎运行脚本期间,界面渲染线程都是处于挂起状态的。也就是说当使用JavaScript对界面中的节点进行操作时,并不会立即体现出来,要等到JavaScript引擎线程空闲时,才会体现出来。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Node.Js中实现端口重用原理详解

JS循环遍历JSON数据的方法

js实现简单登录功能的实例代码

Das obige ist der detaillierte Inhalt vonEine ausführliche Erklärung des JavaScript-Timing-Mechanismus (einschließlich Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Apr 03, 2024 am 11:55 AM

Die Technologie zur Gesichtserkennung und -erkennung ist bereits eine relativ ausgereifte und weit verbreitete Technologie. Derzeit ist JS die am weitesten verbreitete Internetanwendungssprache. Die Implementierung der Gesichtserkennung und -erkennung im Web-Frontend hat im Vergleich zur Back-End-Gesichtserkennung Vor- und Nachteile. Zu den Vorteilen gehören die Reduzierung der Netzwerkinteraktion und die Echtzeiterkennung, was die Wartezeit des Benutzers erheblich verkürzt und das Benutzererlebnis verbessert. Die Nachteile sind: Es ist durch die Größe des Modells begrenzt und auch die Genauigkeit ist begrenzt. Wie implementiert man mit js die Gesichtserkennung im Web? Um die Gesichtserkennung im Web zu implementieren, müssen Sie mit verwandten Programmiersprachen und -technologien wie JavaScript, HTML, CSS, WebRTC usw. vertraut sein. Gleichzeitig müssen Sie auch relevante Technologien für Computer Vision und künstliche Intelligenz beherrschen. Dies ist aufgrund des Designs der Webseite erwähnenswert

PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen Dec 18, 2023 pm 03:39 PM

Mit der rasanten Entwicklung der Internetfinanzierung sind Aktieninvestitionen für immer mehr Menschen zur Wahl geworden. Im Aktienhandel sind Kerzendiagramme eine häufig verwendete Methode der technischen Analyse. Sie können den sich ändernden Trend der Aktienkurse anzeigen und Anlegern helfen, genauere Entscheidungen zu treffen. In diesem Artikel werden die Entwicklungskompetenzen von PHP und JS vorgestellt, der Leser wird zum Verständnis des Zeichnens von Aktienkerzendiagrammen geführt und es werden spezifische Codebeispiele bereitgestellt. 1. Aktien-Kerzendiagramme verstehen Bevor wir uns mit dem Zeichnen von Aktien-Kerzendiagrammen befassen, müssen wir zunächst verstehen, was ein Kerzendiagramm ist. Candlestick-Charts wurden von den Japanern entwickelt

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

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

Die Beziehung zwischen js und vue Die Beziehung zwischen js und vue Mar 11, 2024 pm 05:21 PM

Die Beziehung zwischen js und vue: 1. JS als Eckpfeiler der Webentwicklung; 2. Der Aufstieg von Vue.js als Front-End-Framework; 3. Die komplementäre Beziehung zwischen JS und Vue; Vue.

So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript Jan 05, 2024 pm 01:37 PM

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

js-Methode zum Aktualisieren der aktuellen Seite js-Methode zum Aktualisieren der aktuellen Seite Jan 24, 2024 pm 03:58 PM

js-Methoden zum Aktualisieren der aktuellen Seite: 1. location.reload(); 2. location.href(); 4. window.location. Detaillierte Einführung: 1. location.reload(), verwenden Sie die Methode location.reload(), um die aktuelle Seite neu zu laden. 2. location.href, Sie können die aktuelle Seite aktualisieren, indem Sie das Attribut location.href usw. festlegen.

Tiefes Verständnis der Mechanismen der Neuberechnung und Darstellung von CSS-Layouts Tiefes Verständnis der Mechanismen der Neuberechnung und Darstellung von CSS-Layouts Jan 26, 2024 am 09:11 AM

CSS-Reflow und Repaint sind sehr wichtige Konzepte bei der Optimierung der Webseitenleistung. Bei der Entwicklung von Webseiten kann uns das Verständnis der Funktionsweise dieser beiden Konzepte dabei helfen, die Reaktionsgeschwindigkeit und das Benutzererlebnis der Webseite zu verbessern. Dieser Artikel befasst sich mit den Mechanismen des CSS-Reflows und Repaints und stellt spezifische Codebeispiele bereit. 1. Was ist CSS-Reflow? Wenn sich die Sichtbarkeit, Größe oder Position von Elementen in der DOM-Struktur ändert, muss der Browser die CSS-Stile neu berechnen und anwenden und dann das Layout neu gestalten

Die KI-Ära von JS ist da! Die KI-Ära von JS ist da! Apr 08, 2024 am 09:10 AM

Einführung in JS-Torch JS-Torch ist eine Deep-Learning-JavaScript-Bibliothek, deren Syntax PyTorch sehr ähnlich ist. Es enthält ein voll funktionsfähiges Tensorobjekt (kann mit verfolgten Farbverläufen verwendet werden), Deep-Learning-Ebenen und -Funktionen sowie eine automatische Differenzierungs-Engine. JS-Torch eignet sich für die Deep-Learning-Forschung in JavaScript und bietet viele praktische Tools und Funktionen zur Beschleunigung der Deep-Learning-Entwicklung. Image PyTorch ist ein Open-Source-Deep-Learning-Framework, das vom Meta-Forschungsteam entwickelt und gepflegt wird. Es bietet einen umfangreichen Satz an Tools und Bibliotheken zum Erstellen und Trainieren neuronaler Netzwerkmodelle. PyTorch ist einfach, flexibel und benutzerfreundlich konzipiert und verfügt über dynamische Berechnungsdiagrammfunktionen

See all articles