js関数の実行プロセスを確認するためのsetTimeoutを説明する例

小云云
リリース: 2017-12-20 09:27:12
オリジナル
1991 人が閲覧しました

setTimeout メソッドは、指定されたミリ秒数の後に関数または計算式を呼び出すために使用されます。この記事ではsetTimeoutからのjs関数の実行処理を中心に紹介しますので、必要な方は参考にしていただければ幸いです。


りー

何?これは昔見た、「5」を印刷し、次に「5」を印刷し、5 が 6 枚印刷されるまで毎秒 5 を印刷するという実装方法ではないでしょうか。ここで疑問が生じます。0、1、2、3、4、5 を順番に出力したい場合はどうすればよいでしょうか。実際、これまでに 2 つの方法があることはわかっていました。1 つは次のようなものです:


for (var i = 0; i < 5; i++) {
      setTimeout(function () {
        console.log(i)
      }, i * 1000);
    }
    console.log(i);
ログイン後にコピー

もう 1 つは次のようなものです:


function log(i){
setTimeout(function(){
console.log(i)
},i*1000)
};
for (var i = 0; i < 5; i++) {
      log(i) ;
    }
    console.log(i);
ログイン後にコピー

冗談を恐れないでください。これまでは、これら 2 つの関数が実際に何に使われるのか理解していませんでした。 、でも今はそうではありません、私は強迫性障害です!そこで、ゆっくり分析してみたところ、上記のコードは、条件が満たされた場合、

for(var i=0;i<5;i++){
(function(e){
setTimeout(function(){
console.log(e)
},i*1000);
})(i);
};
console.log(i);
ログイン後にコピー

i=1 の場合、

setTimeout(function(){
console.log(i)
},0*1000);
ログイン後にコピー

i =2 の場合;


setTimeout(function(){
console.log(i)
},1*1000);
ログイン後にコピー

i=3 の場合;


rreee の場合

i=5、条件が満たされていない、ループから抜け出し、for ループの後に console.log(i) を実行し、最終的に 5 を毎秒出力します

非常に興味深いですね、なぜコンソールなのか。 setTimeout内のlogはforループ外のconsole.logの後に実行されます 毛織物? => "キュー" という言葉を理解するまで、キューはマクロタスクキュー (Macro Task) とマイクロタスクキュー (Micro Task) に分かれていました。 、setImmediate、I/O、UI レンダリング。


マイクロタスクには、process.nextTick、Promises、Object.observe、MutationObserverが含まれます

上記関数のsetTimeoutはマクロタスクです

jsでは、イベントループの順序はスクリプトから始まる最初のループです。次にグローバルコンテキスト 関数呼び出しスタックに入り、マクロタスクに遭遇した場合、それを処理するモジュールに渡します。マイクロタスクに遭遇した場合、コールバック関数をマクロタスクキューに入れます。コールバック関数をキュー内のマイクロタスクに入れます。関数呼び出しスタックがクリアされ、グローバル実行コンテキストのみが残るまで、すべてのマイクロタスクが実行され始めます。 すべての実行可能なマイクロタスクが実行された後。ループはマクロタスク内のタスクキューを再度実行し、実行後にすべてのマイクロタスクを実行し、このようにループが続きます。

これが、setTimeout 内の console.log が for ループの外側の console.log の後に実行される理由です。関数実行コンテキストでは、seiTimeout 関数はマクロタスクを処理するためにキューに配置されるため、ループはsetTimeout 内の関数は実行されませんが、キュー内の関数が実行される前に、コード全体 (キュー以外) の実行が完了するまで待機します。これを書くのは少し混乱するかもしれません。実際、私も少し混乱しています。 、 ははは! !

理解を深めるために、Promise を追加してみることもできます。

setTimeout(function(){
console.log(i)
},2*1000);
ログイン後にコピー

説明してください =>

1 まず、スクリプト タスク ソースが実行され、グローバル コンテキストがスタックにプッシュされます。

2. スクリプト タスクのソース コードが実行中に setTimeout に遭遇すると、マクロタスクとして、そのコールバック関数が独自のキューに入れられます。

3. スクリプトタスクソースのコードは、実行中に Promise インスタンスに遭遇します。 Promise コンストラクターの最初のパラメーターは、現在のタスクが直接実行される場合はキューに入れられないため、この時点では 1 が出力されます。

4. forループ内でresolve関数に遭遇すると、関数はスタックにプッシュされてからポップアウトされます。このとき、PromiseのステータスはFulfilledになります。次に、コードが実行され、console.log(2) が検出され、2 が出力されます。

5. 次に実行すると、コードは then メソッドに遭遇し、そのコールバック関数がマイクロタスクとしてスタックにプッシュされ、Promise のタスクキューに入ります。このとき、Promise の then の関数コールバック関数も同様です。つまり、関数コンテキスト、つまりスクリプト内のすべての非キュー コードが実行され、マイクロタスク キューが処理されるまで、それらはそれぞれのタスク キューに配置されます。マクロタスク キューの前に、

全体的な順序は次のとおりです: コンテキスト非キュー コード > マイクロタスク キュー コールバック関数コード > マクロタスク キュー コールバック関数コード

6 その後、コードが実行され、console.log(3) が次のようになります。このとき検出されたため、3 が出力されます。

7. 3 を出力した後、最初のマクロタスク スクリプトのコードが実行され、この時点でキュー内のすべてのマイクロタスクの実行が開始されます。 then のコールバック関数はスタックにプッシュされ、その後ポップアウトされます。この時点で、すべてのマイクロタスクが完了し、最初のサイクルが終了します。 2回目のループはsetTimeoutのタスクキューから始まり、setTimeoutのコールバック関数がスタックにプッシュされてからポップアウトされます。このとき、4が出力されます。

最後に、理解を深めるために、別のコードを示します:

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来实现轮循动画的实例详解

以上がjs関数の実行プロセスを確認するためのsetTimeoutを説明する例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート