Heim  >  Artikel  >  Web-Frontend  >  Beispiele zur Erläuterung von setTimeout, um den Ausführungsprozess der js-Funktion zu sehen

Beispiele zur Erläuterung von setTimeout, um den Ausführungsprozess der js-Funktion zu sehen

小云云
小云云Original
2017-12-20 09:27:121976Durchsuche

Die setTimeout-Methode wird verwendet, um eine Funktion oder einen berechneten Ausdruck nach einer angegebenen Anzahl von Millisekunden aufzurufen. In diesem Artikel wird hauptsächlich der Ausführungsprozess der js-Funktion von setTimeout vorgestellt. Freunde, die ihn benötigen, können darauf zurückgreifen.


for (var i = 0; i < 5; i++) {
      setTimeout(function () {
        console.log(i)
      }, i * 1000);
    }
    console.log(i);

Was? Ist das nicht die Implementierungsmethode, die ich vor langer Zeit gesehen habe, nämlich eine 5, dann eine 5 und dann jede Sekunde eine 5 zu drucken, bis 6 5er gedruckt sind? Hier kommt also die Frage: Was soll ich tun, wenn ich 0, 1, 2, 3, 4, 5 nacheinander drucken möchte? Tatsächlich wusste ich schon vorher, dass es diese beiden Methoden gibt: Eine sieht so aus:


function log(i){
setTimeout(function(){
console.log(i)
},i*1000)
};
for (var i = 0; i < 5; i++) {
      log(i) ;
    }
    console.log(i);

Es gibt noch so einen:


for(var i=0;i<5;i++){
(function(e){
setTimeout(function(){
console.log(e)
},i*1000);
})(i);
};
console.log(i);

Ich habe keine Angst vor Witzen. Ich verstehe diese beiden nicht. Was ist die wahre Funktion dieser Funktion? Ich zwinge mich, sie mir so zu merken, aber sie funktioniert jetzt nicht. Also habe ich es langsam analysiert und festgestellt, dass der obige Code wie folgt unterteilt werden kann:

i=0, wenn die Bedingung erfüllt ist; 🎜 >i=1; die Bedingung erfüllen;


setTimeout(function(){
console.log(i)
},0*1000);
i=2; die Bedingung erfüllen; >

Wenn i=3; die Bedingung erfüllt ist


setTimeout(function(){
console.log(i)
},1*1000);
Wenn i=4 ist; >

Wenn i=5 ist, ist die Bedingung nicht erfüllt, springen Sie aus der Schleife und führen Sie dann console.log(i) nach der for-Schleife aus. Drucken Sie schließlich 5 und geben Sie jede Sekunde 5 aus ;

Es ist wirklich interessant, warum wird das console.log innerhalb von setTimeout nach dem console.log außerhalb der for-Schleife ausgeführt? Bis ich das Wort => „Warteschlange“ erkannte, sind Warteschlangen in Makroaufgabenwarteschlange (Makroaufgabe) und Mikroaufgabenwarteschlange (Mikroaufgabe) unterteilt. In Javascript:
setTimeout(function(){
console.log(i)
},2*1000);

Makroaufgabe enthält: Skript (Gesamtcode). , setTimeout, setInterval, setImmediate, I/O, UI-Rendering.

Mikroaufgabe umfasst: Process.nextTick, Promises, Object.observe, MutationObserver

Das setTimeout der obigen Funktion gehört zur Makroaufgabe
setTimeout(function(){
console.log(i)
},3*1000);

In js die Reihenfolge der Ereignisschleife Die erste Schleife beginnt mit dem Skript, und dann gelangt der globale Kontext in den Funktionsaufrufstapel. Wenn eine Makroaufgabe auftritt, wird sie an das Modul übergeben, das sie verarbeitet. Nach der Verarbeitung wird die Rückruffunktion eingefügt die Warteschlange der Makroaufgabe. Wenn eine Mikroaufgabe auftritt, stellt -task auch seine Rückruffunktion in die Mikroaufgabenwarteschlange. Bis der Funktionsaufrufstapel gelöscht ist und nur noch der globale Ausführungskontext übrig ist, werden alle Mikroaufgaben ausgeführt. Nachdem alle ausführbaren Mikroaufgaben ausgeführt wurden. Die Schleife führt erneut eine Aufgabenwarteschlange in der Makroaufgabe aus und führt dann nach der Ausführung alle Mikroaufgaben aus, und die Schleife wird fortgesetzt.

Aus diesem Grund wird das console.log innerhalb von setTimeout nach dem console.log außerhalb der for-Schleife ausgeführt. Im Funktionsausführungskontext wird die seiTimeout-Funktion in die Warteschlange gestellt, um ihre Makroaufgabe zu verarbeiten. , sodass die Funktion in setTimeout nicht während der Schleife ausgeführt wird, sondern wartet, bis der gesamte Code (nicht in der Warteschlange) ausgeführt wird, bevor die Funktion in der Warteschlange ausgeführt wird. Beim Schreiben bin ich möglicherweise etwas verwirrt Tatsächlich bin ich auch etwas verwirrt, hahaha! !

Um Ihr Verständnis zu vertiefen, können Sie auch versuchen, Promise hinzuzufügen. Hier ist Folgendes:
setTimeout(function(){
console.log(i)
},4*1000);

Erklären Sie es=>

1. Zuerst wird die Skript-Aufgabenquelle ausgeführt und der globale Kontext auf den Stapel verschoben.

2. Wenn der Quellcode der Skriptaufgabe während der Ausführung auf setTimeout stößt, stellt er als Makroaufgabe seine Rückruffunktion in seine eigene Warteschlange.

3. Der Code der Skriptaufgabenquelle trifft während der Ausführung auf eine Promise-Instanz. Der erste Parameter im Promise-Konstruktor ist, dass die aktuelle Aufgabe nicht in die Warteschlange gestellt wird, wenn sie direkt ausgeführt wird, sodass zu diesem Zeitpunkt 1 ausgegeben wird.

4. Wenn Sie in der for-Schleife auf die Auflösungsfunktion stoßen, wird die Funktion in den Stapel verschoben und dann herausgeholt. Zu diesem Zeitpunkt wird der Status „Versprechen“ erfüllt. Der Code wird dann ausgeführt und trifft auf console.log(2), das 2 ausgibt.

5. Dann trifft der Code auf die Methode then und ihre Rückruffunktion wird als Mikroaufgabe auf den Stapel verschoben und in die Aufgabenwarteschlange von Promise eingegeben von Promise und der Funktion in setTimeout Die Rückruffunktionen haben die gleiche Bedeutung und werden in ihre jeweiligen Aufgabenwarteschlangen gestellt

Sie werden erst ausgeführt, wenn der Funktionskontext, also der gesamte Nicht-Warteschlangencode in Skript wurde ausgeführt. Darüber hinaus hat die Mikrotask-Warteschlange Vorrang vor der Makrotask-Warteschlange.

Die Gesamtsequenz ist: Kontext-Nicht-Warteschlangencode > Rückruffunktionscode der Mikrotask-Warteschlange > Rückruffunktionscode der Makrotask-Warteschlange
(function copy() {
  setTimeout(function() {console.log(4)}, 0);
  new Promise(function executor(resolve) {
    console.log(1);
    for( var i=0 ; i<10000 ; i++ ) {
      i == 9999 && resolve();
    }
    console.log(2);
  }).then(function() {
    console.log(5);
  });
  console.log(3);
})()

6. Der Code wird weiterhin ausgeführt und die Konsole wird zu diesem Zeitpunkt auf log(3) gestoßen, Ausgabe 3.

7. Nach der Ausgabe von 3 wird der Code des ersten Makrotask-Skripts ausgeführt. Zu diesem Zeitpunkt beginnen alle Mikrotasks in der Warteschlange ausgeführt zu werden. Die Rückruffunktion wird auf den Stapel verschoben und dann ausgegeben. Zu diesem Zeitpunkt sind alle Mikroaufgaben abgeschlossen und die erste Runde der Schleife endet. Die zweite Runde der Schleife beginnt mit der Rückruffunktion von setTimeout und wird in den Stapel verschoben. Zu diesem Zeitpunkt wird 4 ausgegeben.

Um das Verständnis zu vertiefen, hier noch ein weiterer Code:

console.log(&#39;golb1&#39;);
setTimeout(function() {
  console.log(&#39;timeout1&#39;);
  new Promise(function(resolve) {
    console.log(&#39;timeout1_promise&#39;);
    resolve();
    setTimeout(function(){
      console.log(&#39;time_timeout&#39;)
    });  
  }).then(function() {
    console.log(&#39;timeout1_then&#39;)
  })
  setTimeout(function() {
   console.log(&#39;timeout1_timeout1&#39;);
  });
})
new Promise(function(resolve) {
  console.log(&#39;glob1_promise&#39;);
  resolve();
  setTimeout(function(){
     console.log(&#39;prp_timeout&#39;)
    });
}).then(function() { console.log(&#39;glob1_then&#39;) })

如果你的执行结果是:golb1=>glob1_promise=>glob1_then=>timeout1=>timeout1_promise=>timeout1_then=>prp_timeout=>time_timeout=>timeout1_timeout1,

可能异步队列算是入门了吧!~~上面的代码看起来有点杂乱,可能用asyns搭配await改造一下会更好,但是这或多或少是鄙人从setTimeout中得到的见解吧

相关推荐:

JavaScript中setTimeout()的使用详解

js中的setTimeout()函数

JavaScript如何使用setTimeout来实现轮循动画的实例详解

Das obige ist der detaillierte Inhalt vonBeispiele zur Erläuterung von setTimeout, um den Ausführungsprozess der js-Funktion zu sehen. 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