Node.jsイベントループティックとは正確には何ですか?


83

Node.jsアーキテクチャの内部について詳しく調べていますが、よく出てくる用語は「イベントループの次のティック」や関数nextTick()のように「ティック」です。

私が見たことがないのは、正確に「カチカチ」が何であるかについての確かな定義です。さまざまな記事(この記事など)に基づいて、頭の中で概念をまとめることができましたが、それがどれほど正確かはわかりません。

Node.jsイベントループティックの正確で詳細な説明を取得できますか?


その「ループ」は「次にループするとき」を意味するので、ループ全体にチェックマークを付けます。イベントがトリガーされないときに終了し、nodejsがすべてループしてトリガーされているかどうかを確認します。現在のものの後にループします。
gntem 2013年

回答:


155

JavaScriptはシングルスレッドですが、ノードのすべてのI / OとネイティブAPIの呼び出しは、非同期(プラットフォーム固有のメカニズムを使用)であるか、別のスレッドで実行されることに注意してください。(これはすべてlibuvを介して処理されます。)

したがって、ソケットで使用可能なデータがある場合、またはネイティブAPI関数が返された場合、発生した特定のイベントに関係するJavaScript関数を呼び出す同期方法が必要です。

通常のマルチスレッドアプリケーションで発生するのと同じ理由(競合状態、非アトミックメモリアクセスなど)で、ネイティブイベントが発生したスレッドからJS関数を呼び出すことは安全ではありません。

したがって、私たちが行うことは、スレッドセーフな方法でイベントをキューに配置することです。過度に単純化された擬似コードでは、次のようになります。

lock (queue) {
    queue.push(event);
}

次に、メインのJavaScriptスレッドに戻ります(ただし、C側では)、次のようなことを行います。

while (true) {
    // this is the beginning of a tick

    lock (queue) {
        var tickEvents = copy(queue); // copy the current queue items into thread-local memory
        queue.empty(); // ..and empty out the shared queue
    }

    for (var i = 0; i < tickEvents.length; i++) {
        InvokeJSFunction(tickEvents[i]);
    }

    // this the end of the tick
}

while (true)(実際には、ノードのソースコードに存在しない、これは純粋に例示的である)を表すイベントループ。内部forは、キューにあったイベントごとにJS関数を呼び出します。

これは目盛りです。外部イベントに関連付けられた0個以上のコールバック関数の同期呼び出しです。キューが空になり、最後の関数が戻ると、ティックは終了します。最初(次のティック)に戻り、JavaScriptの実行中に他のスレッドからキューに追加されたイベントを確認します。

キューに何を追加できますか?

  • process.nextTick
  • setTimeout/setInterval
  • I / O(からのものfsnetなど)
  • crypto暗号ストリーム、pbkdf2、PRNGなどのプロセッサを集中的に使用する関数(実際には...の例です)
  • libuvワークキューを使用して同期C / C ++ライブラリ呼び出しを非同期に見えるようにするネイティブモジュール

2
ええ、あなたはこれを釘付けにしました。キューのコピーとコピー上のすべてのイベントの実行は、私が特に疑問に思っていたものでした。しかし、今では非常に理にかなっています。ありがとう。
d512 2013年

これは有名な「非同期反復パターン」アルゴですか?
Stef 2014

1
@sanjeev、「通常の仕事」とはどういう意味ですか?進行中のJavaScriptアプリケーションが実行するのは、プロセスイベントだけです。
josh3736 2014

2
0.10.xsetImmediateでも関数をキューに入れることを追加したいと思います。
DanielKhan 2015

1
ティックはイベントループフェーズを意味しますか?
faressoft 2016年

10

JavaScriptを初めて使用する人のためのより簡単な答え:

最初に理解することは、JavaScriptは「シングルスレッド環境」であることです。これは、単一のスレッドで「イベントループ」からコードのブロックを一度に1つずつ実行するJavaScriptの動作を指します。以下に、Kyle Simpsonの本ydkJSから取得したイベントループの基本的な実装と、その後の説明を示します。

// `eventLoop` is an array that acts as a queue (first-in, first-out)
var eventLoop = [ ];
var event;

// keep going "forever"
while (true) {
    // perform a "tick"
    if (eventLoop.length > 0) {
        // get the next event in the queue
        event = eventLoop.shift();

        // now, execute the next event
        try {
            event();
        }
        catch (err) {
            reportError(err);
        }
    }
}

最初のwhileループは、イベントループをシミュレートします。ティックとは、「イベントループキュー」からのイベントのデキューと、そのイベントの実行です。

イベントのデキューと実行で何が起こるかについてのより詳細な説明については、「Josh3796」の応答を参照してください。

また、JavaScriptを深く理解したい人には、カイルシンプソンの本を読むことをお勧めします。これは完全に無料でオープンソースであり、次のリンクで見つけることができます:https//github.com/getify/You-Dont-Know-JS

私が参照した特定のセクションはここにあります:https//github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md


1

イベントループティックの非常に単純で短い方法は次のとおりです。

これは、キュー上の一連の要求が処理されると、タスクの完了を表すティックが開始されるノード内部メカニズムによって使用されます。


答えの出典を教えていただけますか?
キックザびっくり
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.