ホームページ >ウェブフロントエンド >jsチュートリアル >JS 実行メカニズムの簡単な分析

JS 実行メカニズムの簡単な分析

零到壹度
零到壹度オリジナル
2018-03-28 14:55:271409ブラウズ

この記事では主に JS の実行メカニズムを簡単に分析する方法を紹介します。これは非常に参考になるので、皆さんのお役に立てれば幸いです。エディターと一緒に見てみましょう

まず、次の 2 つの点に留意してください:

(1) JS はシングルスレッド言語です

(2) JSのイベントループはJSの実行機構です。 JS の実行を深く理解することは、JS

1 のイベント ループを深く理解することに相当します。なぜ JS はシングルスレッドなのか? なぜシングルスレッドが必要なのか?

テクノロジーの外観は、現実世界のアプリケーション シナリオと密接に関連しています。

同様に、実際のシナリオに基づいてこれら 3 つの質問に答えます

(1) JS はなぜシングルスレッドですか?

JS は元々ブラウザで使用されるように設計されているため、JS がブラウザはマルチスレッドです。

このように考えると、JS がシングルスレッドになるように設計されている理由が簡単に理解できるはずです。

(2) JS に非同期が必要な理由


1

2

3

4

5


シナリオの説明:

これで、2プロセスprocess1が存在します プロセス2があるのでプロセスの JS は同じ dom 上で同時に動作します

process1 dom process2 を削除しました これを編集しました dom 同時に 2 つの 矛盾するコマンドを発行しました ブラウザはそれらをどのように実行すべきですか?


1

2

3

4


シーン説明:

JS に非同期 がない場合、 は上から下へのみ実行できます 前の行の解析時間が非常に長い 場合、次のコードはブロックされます。

ユーザーにとってブロックとは「スタック」を意味し、これは非常に質の悪いユーザーエクスペリエンスにつながります

つまり、JSには非同期実行が存在します。

(3) シングルスレッドの JS はどのようにして非同期実装を実現しますか?

JS はシングルスレッドで 1 つのスレッドでのみ実行できるため、どのようにして非同期実装を実現しますか?

はいイベントループ(イベントループ)、イベントループの仕組みが理解できれば、JS

2の実行の仕組みも理解できます。 JS

例1のイベントループ(1)、その実行シーケンスを観察してください

 console.log(1)
    
    setTimeout(function(){
        console.log(2)
    },0)
 
    console.log(3)

結果は次のようになります: 1 3 2

つまり、setTimeout の関数はすぐには実行されず、一定期間遅延して、特定の条件が満たされた後にのみ実行されます。このタイプのコードは非同期コードと呼ばれます。

それでは、ここでまず JS の分類方法を知ります。それは、タスクを次のとおりに分けることです: 同期タスクと非同期タスク

画像の説明

この分類方法によると: JS の実行メカニズムは

  • まずall JS が同期か非同期かを決定します。同期の場合はメイン プロセスに入り、非同期のタスクはトリガー条件が満たされるとイベント テーブルに関数を登録します。同期タスクはメイン プロセスに入ります。スレッドはメイン スレッドがアイドルになるまで実行を続けます。その後、実行可能な非同期タスクがあるかどうかを確認するためにイベント キューに移動します。存在する場合は、それらをメイン プロセスにプッシュします。

  • 上記の3つのステップをループで実行します。これがイベントループです

    それでは、上記の例について、その実行順序を説明していただけますか?

    コンソール.
    log


    (

    1

    )

    は同期タスクです

    メインスレッドに入れてください

    setTimeout() は非同期タスクイベントtable 0秒後にプッシュされますイベント キュー

    コントロール ストリップが印刷された後メインスレッドはeventqueue(Event Queue)に進み、実行可能な関数があるかどうかを確認し、関数を実行します

    タイムアウトを設定する

    3.JS中的event loop(2)

    所以,上面关于event loop就是我对JS执行机制的理解,直到我遇到了下面这段代码

    例2:

    setTimeout(function(){
         console.log('定时器开始啦')
     });
     
     new Promise(function(resolve){
         console.log('马上执行for循环啦');
         for(var i = 0; i

    尝试按照,上文我们刚学到的JS执行机制去分析


    1

    2

    3

    4

    5

    6

    7


    setTimeout は非同期タスクであり、event table

    new に配置されます約束 は同期タスクが配置されていますメインプロセスでは、印刷を直接実行します console.log('今すぐforループを実行します')

    . それでははい 非同期タスク event table

    に配置されます

    console.log('コード実行終了')は同期コードはメインプロセスに配置され直接実行される

    結果は、[forループをすぐに実行 - コードの実行が終了 - タイマーが開始 - その後関数が実行される] ということでしょうか

    自分で実行してみると、結果はこうではありませんが、 [forループをすぐに実行 - コードの実行] 終了- then 関数が実行される - タイマーが開始する]

    ということは、非同期タスクの実行順序は前後の順序ではなく、実際には非同期と同期の区別が正確ではありません。

    正確な分割方法は次のとおりです:

    • マクロタスク (マクロタスク): コードスクリプト全体、setTimeout、setInterval を含む

    • マイクロタスク (マイクロタスク): Promise、process.nextTick

    JS 実行メカニズムの簡単な分析

    この分類方法によると、JS の実行メカニズムは

    • プロセス中にマイクロ タスクが発生すると、マイクロの [イベント キュー] に配置されます。タスク

    • 現在のマクロ タスクの実行が完了すると、マイクロタスクの[イベントキュー]が表示され、その中のすべてのマイクロタスクが順番に実行されます。上記の2つの手順を繰り返し、イベントループ( 1) イベント ループ (2)、より正確な JS 実行メカニズム。

    • 先ほど学んだ実行メカニズムに従って例 2 を分析してみてください:


    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14


    まずscriptの下でマクロタスクを実行し、遭遇setTimeoutし、マクロタスクの[キュー]に入れます

    遭遇 new Promise 直接実行します,Print「今すぐforループを実行します」

    次にメソッドに遭遇、それはマイクロタスクですマイクロタスクの[キュー]に入れます

    Print

    「コードの実行が終了しました」

    このラウンドのマクロタスクが実行されました

    このラウンドのマイクロタスクを表示I found a function in the thenメソッド Print「実行そして関数「

    これで

    今回のラウンドのイベントループ 」が全て完了しました。

    下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"

    所以最后的执行顺序是【马上执行for循环啦 — 代码执行结束 — 执行then函数啦 — 定时器开始啦】

    4. 谈谈setTimeout

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

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

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

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

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

以上がJS 実行メカニズムの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。