Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Ausführungsmechanismus der JS-Engine

Detaillierte Erläuterung des Ausführungsmechanismus der JS-Engine

小云云
小云云Original
2018-03-31 17:11:112974Durchsuche


Dieser Artikel teilt Ihnen hauptsächlich die detaillierte Erklärung des Ausführungsmechanismus der js-Engine mit und hofft, allen zu helfen.

Bitte beachten Sie zunächst zwei Punkte:

  • js ist eine Single-Threaded-Sprache

  • Das Ereignis Die Schleife in js ist der Ausführungsmechanismus von js. Ein tiefes Verständnis der Ausführung von js entspricht einem tiefen Verständnis der Ereignisschleife in js

Warum ist js Single-Threaded?

js wurde ursprünglich für die Verwendung in Browsern entwickelt. Stellen Sie sich also vor, js im Browser wäre multithreaded.

Szenariobeschreibung:

Es gibt also zwei Prozesse, Prozess1 und Prozess2. Da es sich um einen Multiprozess handelt, arbeiten sie gleichzeitig auf demselben Dom , und Process2 hat das DOM bearbeitet und gleichzeitig zwei widersprüchliche Befehle ausgegeben. Wie soll der Browser sie ausführen?

Wenn man es so betrachtet, sollte es leicht zu verstehen sein, warum js für Single-Threading konzipiert ist.

Warum braucht js asynchron?

Szenenbeschreibung;

Wenn es in js keine Asynchronität gibt, kann es nur von oben nach unten ausgeführt werden. Wenn die Analysezeit der vorherigen Zeile sehr lang ist, wird der folgende Code ausgeführt blockiert. Für Benutzer bedeutet das Blockieren, dass sie „stecken bleiben“, was zu einer schlechten Benutzererfahrung führt.

Es gibt also eine asynchrone Ausführung in js.

Wie erreicht ein einzelner Thread eine asynchrone Implementierung?

Da JS Single-Threaded ist und nur in einem Thread ausgeführt werden kann, wie erreicht man eine asynchrone Implementierung?

Wir verstehen die Funktion von js Ausführungsmechanismus.

Ereignisschleife (1) in js

console.log(1);
setTimeout(function() {
  console.log(2);
}, 0);
console.log(3);// 输出 1 3 2

Mit anderen Worten, die Funktion in setTimeout wird nicht sofort ausgeführt, sondern um einen bestimmten Zeitraum verzögert und erst nach bestimmten Bedingungen ausgeführt Diese Art von Code, der ausgeführt wird, wird als asynchroner Code bezeichnet.

Hier kennen wir also zunächst eine Klassifizierungsmethode in JS, die darin besteht, Aufgaben in synchrone Aufgaben und asynchrone Aufgaben zu unterteilen

Gemäß dieser Klassifizierungsmethode ist der Ausführungsmechanismus von js:

  • Bestimmen Sie zunächst, ob das js synchron oder asynchron ist. Wenn es synchron ist, wird es in den Hauptthread eingegeben, wenn es asynchron ist, wird es in die Ereignistabelle eingegeben

  • Asynchrone Aufgaben sind im Ereignis. Die Funktion wird in der Tabelle registriert. Wenn die Auslösebedingung erfüllt ist, wird sie in die Ereigniswarteschlange verschoben.

  • Die Synchronisierungsaufgabe wird eingegeben Der Hauptthread wird ausgeführt, bis der Hauptthread inaktiv ist. Anschließend wird in der Ereigniswarteschlange überprüft, ob ausführbare asynchrone Aufgaben vorhanden sind. Wenn ja, werden sie an den Hauptthread weitergeleitet.

Die obige dreistufige Schleifenausführung ist die Ereignisschleife

Können Sie also für das obige Beispiel die Ausführungsreihenfolge beschreiben?

console.log(1); // 同步任务,放入主线程中setTimeout(function() {
  // 异步任务,放到event table中,0秒后被推入到event queue中
  console.log(2);
}, 0);
console.log(3); // 同步任务,放到主线程中// 输出 1 3 2// 当1,3被打印后,主线程去event queue(事件队列)里查看是否有可执行的函数,执行setTimeout里面的函数。

Ereignisschleife (2) in js

Sehen Sie sich das nächste Beispiel an:

setTimeout(function() {
  console.log("定时器开始");
}, 0);new promise(function(resolve) {
  console.log("马上执行for循环了");
}).then(function(resolve) {
  console.log("执行then函数拉");
});
console.log("代码执行结束");

Verwenden Sie den zuvor zusammengefassten js-Ausführungsmechanismus zur Analyse:

setTimeout 是异步任务,放在 event table中new promise是同步任务,被放到主线程中,直接打印console.log('马上执行for循环了');

.then里面的是异步任务,被放到event table中

console.log('代码执行结束') 是同步代码,被放在主线程中,直接执行。

Das Ergebnis ist also [for-Schleife sofort ausführen – die Codeausführung endet – der Timer startet – die then-Funktion wird ausgeführt]?

Nachdem ich es selbst ausgeführt habe, ist das Ergebnis nicht so Dies, aber es ist [die for-Schleife sofort ausführen – die Codeausführung endet – die then-Funktion ausführen – der Timer startet]

Ist es also die Ausführungsreihenfolge asynchroner Aufgaben, nicht die Reihenfolge davor und danach, sondern Andere Vorschriften? Tatsächlich ist die Divisionsmethode von asynchron und synchron nicht genau

, aber die genaue Divisionsmethode ist:

  • Makroaufgabe (Makro). Aufgabe): Gesamtcode-Skript, setTimeout, setInterval

  • Mikroaufgabe (Mikroaufgabe): Versprechen, Prozess, nextTick

Detaillierte Erläuterung des Ausführungsmechanismus der JS-Engine

Folgen Sie dieser Klassifizierungsmethode. Der Ausführungsmechanismus von js lautet:

  • Führen Sie eine Makroaufgabe aus, wenn während des Prozesses eine Mikroaufgabe auftritt in die Ereigniswarteschlange der Mikroaufgabe gestellt

  • Nachdem die Ausführung der aktuellen Makroaufgabe abgeschlossen ist, wird die Ereigniswarteschlange der Mikroaufgabe überprüft und alle darin enthaltenen Mikroaufgaben werden überprüft der Reihe nach ausgeführt.

Wiederholen Sie die beiden oben genannten Schritte in Kombination mit der Ereignisschleife (1) und der Ereignisschleife (2), um einen genaueren JS-Ausführungsmechanismus zu erhalten.

Analysieren Sie anhand des Mechanismus gerade Beispiel 2:

// 首先执行script下的宏任务,遇到setTimeout,将其放在宏任务队列中setTimeout(function() {
  console.log("定时器开始");
}, 0);// 遇到new promise直接执行new promise(function(resolve) {
  console.log("马上执行for循环了");
}).then(function(resolve) {
  // .then方法,是微任务,放在微任务队列中
  console.log("执行then函数拉");
});
console.log("代码执行结束");// 宏任务执行完毕,查看本轮的微任务,返现有一个then方法。再去执行宏任务队列中的函数。

Sprechen Sie über setTimeout

Was bedeutet dieser setTimeout-Code? Wir sagen im Allgemeinen: Er wird ausgeführt nach 3 Sekunden Die Funktion in setTimeout

setTimeout(function() {
  console.log("执行了");
}, 3000);

Dies ist jedoch nicht streng. Die genaue Erklärung lautet: Nach 3 Sekunden wird die Funktion in setTimeout in die Ereigniswarteschlange verschoben (Ereigniswarteschlange). ) Die Aufgabe wird nur ausgeführt, wenn der Hauptthread inaktiv ist.

Also nur, wenn (1) 3 Sekunden später (2) der Hauptthread inaktiv ist und beide erfüllt sind, wird die Funktion nach 3 Sekunden ausgeführt

Wenn der Hauptthread führt viele Inhalte aus. Wenn die Ausführungszeit 3 ​​Sekunden überschreitet. Wenn sie beispielsweise 10 Sekunden lang ausgeführt wird, kann diese Funktion erst nach 10 Sekunden ausgeführt werden.

Umfassendes Verständnis der Ausführungsmechanismus der js-Engine

Bitte beachten Sie zunächst zwei Punkte:

  • js ist eine Single-Threaded-Sprache

  • Die Ereignisschleife in js ist der Ausführungsmechanismus von js. Ein tiefes Verständnis der Ausführung von js entspricht einem tiefen Verständnis der Ereignisschleife in js

Warum ist js Single-Threaded?

js wurde ursprünglich für die Verwendung in Browsern entwickelt. Stellen Sie sich also vor, js im Browser wäre multithreaded.

Szenenbeschreibung:

那么现在有 2 个进程,process1 process2,由于是多进程的 js,所以他们对同一个 dom,同时进行操作,process1 删除了该 dom,而 process2 编辑了该 dom,同时下达 2 个矛盾的命令,浏览器究竟该如何执行呢?

这样想,js 为什么被设计成单线程应该就容易理解了吧。

js 为什么需要异步?

场景描述;

如果 js 中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。对于用户而言,阻塞就意味着‘卡死’,这样就导致了很差的用户体验。

所以,js 中存在异步执行。

单线程又是如何实现异步的呢?

既然 JS 是单线程的,只能在一条线程上执行,又是如何实现的异步呢?

是通过的事件循环(event loop), 就理解了 js 的执行机制。

js 中的 event loop(1)

console.log(1);
setTimeout(function() {
  console.log(2);
}, 0);
console.log(3);// 输出 1 3 2

也就是说,setTimeout 里的函数并没有立即执行,而是延迟了一段时间,满足一定条件后,才去执行的,这类代码,我们叫异步代码。

所以,这里我们首先知道了 JS 里的一种分类方式,就是将任务分为: 同步任务和异步任务

按这种分类方式,js 的执行机制就是:

  • 首先判断 js 是同步的还是异步的,同步的就进入主线程,异步就进入 event table

  • 异步任务在 event table 中注册函数,当满足触发条件后,被推入 event queue

  • 同步任务进入主线程后一直执行,直到主线程空闲,才会去 event queue 中查看是否有可执行的异步任务,若果有就推入到主线程中。

以上三步循环执行,就是 event loop

所以上述例子,你是否可以描述他们的执行顺序了?

console.log(1); // 同步任务,放入主线程中setTimeout(function() {
  // 异步任务,放到event table中,0秒后被推入到event queue中
  console.log(2);
}, 0);
console.log(3); // 同步任务,放到主线程中// 输出 1 3 2// 当1,3被打印后,主线程去event queue(事件队列)里查看是否有可执行的函数,执行setTimeout里面的函数。

js 中的 event loop(2)

再看下一个例子:

setTimeout(function() {
  console.log("定时器开始");
}, 0);new promise(function(resolve) {
  console.log("马上执行for循环了");
}).then(function(resolve) {
  console.log("执行then函数拉");
});
console.log("代码执行结束");

用之前总结的 js 执行机制去分析:

setTimeout 是异步任务,放在 event table中new promise是同步任务,被放到主线程中,直接打印console.log('马上执行for循环了');

.then里面的是异步任务,被放到event table中

console.log('代码执行结束') 是同步代码,被放在主线程中,直接执行。

所以,结果是 【马上执行 for 循环啦 — 代码执行结束 — 定时器开始啦 — 执行 then 函数啦】吗?

亲自执行后,结果居然不是这样,而是【马上执行 for 循环啦 — 代码执行结束 — 执行 then 函数啦 — 定时器开始啦】

那么,难道是异步任务的执行顺序,不是前后顺序,而是另有规定? 事实上,按照异步和同步的划分方式,并不准确

而准确的划分方式是:

  • macro-task(宏任务): 整体代码 script, setTimeout,setInterval

  • micro-task(微任务): Promise,process,nextTick

Detaillierte Erläuterung des Ausführungsmechanismus der JS-Engine

按照这种分类方式,js 的执行机制就是:

  • 执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的 event queue 中

  • 当前宏任务执行完成后,会常看微任务的 event queue ,并将里面全部的微任务依次执行完。

重复以上 2 步骤,结合 event loop(1) event loop(2) ,就是更为准确的 JS 执行机制了。

按照刚才的机制,分析例 2:

// 首先执行script下的宏任务,遇到setTimeout,将其放在宏任务队列中setTimeout(function() {
  console.log("定时器开始");
}, 0);// 遇到new promise直接执行new promise(function(resolve) {
  console.log("马上执行for循环了");
}).then(function(resolve) {
  // .then方法,是微任务,放在微任务队列中
  console.log("执行then函数拉");
});
console.log("代码执行结束");// 宏任务执行完毕,查看本轮的微任务,返现有一个then方法。再去执行宏任务队列中的函数。

谈谈 setTimeout

这段 setTimeout 代码什么意思? 我们一般说: 3 秒后,会执行 setTimeout 里的那个函数

setTimeout(function() {
  console.log("执行了");
}, 3000);

但是这种说并不严谨,准确的解释是: 3 秒后,setTimeout 里的函数被会推入 event queue,而 event queue(事件队列)里的任务,只有在主线程空闲时才会执行。

所以只有满足 (1)3 秒后 (2)主线程空闲,同时满足时,才会 3 秒后执行该函数

如果主线程执行内容很多,执行时间超过 3 秒,比如执行了 10 秒,那么这个函数只能 10 秒后执行了

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Ausführungsmechanismus der JS-Engine. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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