setTimeout-set IntervalからJSスレッドを見ます.

5388 ワード

最近のプロジェクトの中で一つのシーンに遭遇しました.実はよく見られます.タイミング取得インターフェースのリフレッシュデータです.問題が来ました.もし私が設定したタイミングが1 sであると仮定して、データインターフェースの戻りは1 sより大きいです.同期ブロックを使うべきですか?それとも非同期ですか?jsのタイマーに関する知識を整理してから、この問題を見に来ます.
初めてsetTimeoutとsetIntervalを知っています.
まず簡単な認識に来てください.後でsetTimeoutを試してsetIntervalの機能を実現します.
  • setTimeoutは、時間をおいて一回実行します.
  • setTimeout(function, milliseconds, param1, param2, ...)
    clearTimeout() //        
    
    e.g.
    setTimeout(function(){ alert("Hello"); }, 3000); // 3s   
  • set Intervalは、時間ごとに一回実行されます.
    setInterval(function, milliseconds, param1, param2, ...)
    
    e.g.
    setInterval(function(){ alert("Hello"); }, 3000); //   3s  
    setTimeoutとsetIntervalの遅延最小間隔は4 msである(W 3 CはHTML標準で規定されている).JavaScriptでは、コードがありません.すぐに実行されますが、空きがあれば、速やかに実行します.これは、設定された時間がnミリ秒以上ではなく、setTimeoutであってもsetIntervalであっても、nミリ秒以上であっても、キューに追加されることを意味する.
    プロセスとスレッドは、愚かで分かりません.
    この二つの抽象的な概念をはっきり説明するために、私たちはチェットから大いに借りた比喩を借りて、まず一つの場面を模擬します.
  • ここに大きな工場があります.
  • 工場にはいくつかの作業場があります.毎回作業場が一つしかありません.
  • 各職場にはいくつかの部屋があります.何人かの労働者がライン作業をしています.
    では、
  • 工場に対応しているのはコンピュータのCPUです.普段話しているマルチコアは複数の工場
  • を表しています.
  • 工場ごとの作業場はプロセスであり、同じ時刻にCPUが一つのプロセスだけを実行し、残りのプロセスはサボタージュ
  • にある.
  • この作業場(プロセス)の中の労働者はスレッドであり、複数の労働者(スレッド)が協力して一つの任務を完成することができます.
  • 作業場の部屋はメモリを表しています.
  • もう少し深いところ:
  • 作業場(プロセス)で労働者が任意に複数の部屋(メモリ)の間を歩き回ることができます.一つのプロセスにおいて、複数のスレッドがメモリ
  • を共有できます.
  • 部分の部屋(メモリ)は限られています.労働者(スレッド)は一人しか使えません.この時、他の労働者(スレッド)は
  • を待ちます.
  • 部屋には労働者が入って施錠します.他の労働者は部屋の中の労働者(スレッド)がロックされてから入ることができます.これは相互反発ロックです.
  • .
  • 一部の部屋には一部しか収容できない人がいます.一部のメモリは限られたスレッド
  • しか与えられません.
    もっと深く:
  • 複数の作業場が同時にある場合、プロセス
  • です.
  • もし一つの職場に複数の労働者が共同作業をすると、マルチスレッド
  • です.
  • もちろん、職場間の労働者も互いに協力し合うことができます.調整メカニズムが必要です.
    JavaScript単スレッド
    よく知られているように、JavaScriptという言語の核心的特徴は単一スレッド(JSエンジンでJavaScriptコードを解釈し実行するスレッドは一つだけ)です.これはJavaScriptの最初の設計はGUIプログラミング言語として関連しています.最初はブラウザの端に用いられ、単一スレッド制御GUIは一般的なやり方です.ただし、ここでは特に、JavaScriptは単一スレッドですが、ブラウザはマルチスレッドです!例えばWebkitやGeckoエンジンは、Javascriptエンジンスレッド、インターフェイスレンダリングスレッド、ブラウザイベントトリガスレッド、Http要求スレッド、ファイルを書くスレッド(例えば、Node.js)があります.ps:ブラウザで書いた文章をまとめたいです.
    HTML 5は、JavaScriptスクリプトが複数のスレッドを作成することを可能にするWeb Worker規格を提案していますが、サブスレッドは完全にリードによって制御され、DOMを操作してはいけません.したがって、この新しい標準はJavaScript単スレッドの本質を変えていません.
    同期と非同期、間抜けで分かりません.
    前にチェットは大きく「JavaScript運行メカニズム詳細解:またEvent Loopについて話します」と書いて、朴霊に評注されました.特に同期非歩の理解において、二人の大牛は大きな違いがあります.
  • 同期(synchronous):もし一つの関数が戻ってきたら、スケジューラは予想される結果を得ることができます.すなわち、期待された戻り値を得たり、予期された効果を見たりします.これは同期関数です.
  • e.g.
    alert('       ');
    console.log('        ');
  • 非同期(asynchronous):もし一つの関数が戻ってきたら、変調者は予期された結果を得ることができず、一定の手段でしか得られない、これが非同期関数です.
  • e.g.
    setTimeout(function() {
        //            
    }, 1000);
    非同期構成要素
    非同期プロセスは、一般的に、メインスレッドが、要求を受信して、ホストスレッドが受信されたことを知らせるための非同期要求を開始する.メインスレッドは、後続のコードを実行しながら、作業スレッドが非同期タスクを実行することができます.作業スレッドが完了したら、メインスレッドに通知します.メインスレッドが通知を受けたら、一定の動作(コールコールコールコールコールコール機能)を実行します.
  • .非同期プロセスの開始(登録)関数
  • コールバック関数--処理結果
  • e.g.
    setTimeout(fn, 1000);
    // setTimeout           ,fn     
    通信システム
    非同期プロセスの通信メカニズム:ワークスレッドはメッセージキューにメッセージを置き、メインスレッドはイベントサイクルプロセスを通してメッセージを取りに行く.
    メッセージ・キューMessage Que
    先进的な行列ができて、いろいろな情报を保存します.
    イベントサイクルイベントループループ
    メインスレッド(jsスレッド)は一つのことしかできません.メッセージ・キューからメッセージを取って実行し、メッセージを取って実行します.メッセージキューが空の場合、メッセージキューが空になるまで待ちます.現在のメッセージの実行が終了してこそ、次のメッセージを取りに行くことができます.このメカニズムはイベントサイクル機構と呼ばれています.
    Event Loopは、メッセージを取って実行するプロセスを一回のループといいます.
    作業スレッドは生産者で、主スレッドは消費者です.作業スレッドは非同期のタスクを実行し、実行が完了したら対応するコールバック関数をメッセージキューに格納する.メインスレッドはメッセージキューからメッセージを継続的に取り出して実行し、メッセージキューが空であるときにメインスレッドがブロックされ、メッセージキューが再び空でないときには元スレッドがブロックされる.
    setTimeout(function、0)に何が起きましたか?
    実はここまで、setTimeout(function、0)というよく使われている「奇術淫巧」をよく説明できるはずです.簡単には、function内のタスクを非同期的に実行するために、0は直ちに実行することを表すのではなく、メッセージ・キューの最後にタスクを押して、メインスレッドのイベントサイクルによって実行を呼び戻すことができる.
    HTML 5でsetTimeoutを規定する最小時間は0 msではなく、4 msである.
    set Interval欠点
    タイマーが指定した時間間隔は、タイマーのコードをいつまで追加するかを再度強調します.
    メッセージ待ち
    コードはいつ実行されますか?したがって、本当にいつコードを実行するかは保証できません.メインスレッドのイベントがいつ取り返されるかによって、実行されます.
    setInterval(function, N)
    このコードは、N秒ごとにFunctionイベントをメッセージ・キューに押して、いつ実行するかを意味することが明白である.母鶏よ
    上の図から分かるように、set Intervalは100 msごとに列にイベントを追加する.100 ms後、T 1タイマーコードをキューに追加すると、メインスレッドではまだタスクが実行されていますので、some eventが実行終了後にT 1タイマーコードを実行します.また100 msを過ぎて、T 2タイマーがキューに追加され、メインスレッドはまだT 1コードを実行しているので、待ちます.また100 msを過ぎて、理論的にはまた列にタイマーコードを押しますが、T 2はまだ列の中にありますので、T 3は追加されません.結果はこの時にスキップされます.ここではT 1タイマーの実行が終了した直後にT 2コードが実行されていますので、タイマーの効果は得られていません.
    以上のように、set Intervalには二つの欠点があります.
  • setIntervalを使用すると、ある間隔がスキップされます.
  • は、複数のタイマーが連続して実行される場合がある.
  • チェーンsetTimeout
    setTimeout(function () {
        //   
        setTimeout(arguments.callee, interval);
    }, interval)
    警告:厳格なモードでは、第5版ECMAScript(ES 5)は、argments.callee()の使用を禁止します.関数が自分自身を呼び出さなければならない場合、アーグメンント.
    上記の関数は、実行するたびに新しいタイマーを作成します.第二のsetTimeoutは、argments.callee()を使用して、現在の関数の参照を取得し、他のタイマーを設定します.利点:
  • は、前のタイマーが実行される前に、新しいタイマー(欠点解決1)
  • をキューに挿入しません.
  • は、タイマー間隔(欠点解決二)
  • を保証する.
    So…
    最初のビジネスシーンを振り返ると、同期でブロックするか、それとも非同期で…
    PS:実はまだmacrotaskとmicrotaskなどの知識点は言及していません.そんなに多くまとめました.実はJavaScriptは深く入り込み続けます.任重くて道が遠いです.
    参考:
    プロセスとスレッドの簡単な説明
    【訳】JavaScriptはどのように仕事をしていますか?イベントサイクルと非同期プログラミングの台頭+5つのASync/awaitを使ってより良い技術を編纂するにはどうすればいいですか?
    すでに個人のブログに同期しました.
    Github歓迎star:)