12

まず第一に、私は Node.Js とは何かを理解しようとしているスターターです。2 つの質問があります。

最初の質問Felix の記事
によると、 「同時に起動できるコールバックは 1 つだけです。そのコールバックの実行が完了するまで、他のすべてのコールバックは順番に待機する必要があります」。

次に、次のコードについて検討します(nodejs公式Webサイトからコピー)

var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");

2 つのクライアント要求が同時に受信された場合、次のワークフローを意味します。

  1. 最初の http 要求イベントを受信し、2 番目の要求イベントを受信しました。
  2. 最初のイベントが受信されるとすぐに、最初のイベントのコールバック関数が実行されます。
  3. その間、2 番目のイベントのコールバック関数が待機する必要があります。

私は正しいですか?私が正しければ、非常に短い時間内に何千ものクライアント リクエストがある場合、 Node.jsがどのように制御するかということです。

2 番目の質問
「イベント ループ」という用語は、主に Node.js トピックで使用されます。http://www.wisegeek.com/what-is-an-event-loop.htmから「イベントループ」を次のように理解しました。

イベント ループ (またはメイン ループ) は、初期イベントに続くイベントを制御およびディスパッチするプログラム内の構造です。

初期イベントは、キーボードのボタンを押す、プログラムのボタンをクリックするなど、何でもかまいません (Node.js では、初期イベントは http 要求、db クエリ、または I/O ファイル アクセスになると思います)。

これがループと呼ばれるのは、イベントが循環して継続的に発生するためではなく、ループがイベントの準備、イベントのチェック、イベントのディスパッチ、プロセスの最初からやり直しを繰り返すためです。

2番目の段落、特に「プロセスをもう一度繰り返す」というフレーズについて矛盾があります。上記の質問からの上記のhttp.createServerコードは、http 要求イベントを繰り返しリッスンするため、完全に「イベント ループ」であることを受け入れました。

しかし、次のコードをイベント ドリブンかイベント ループかを識別する方法がわかりません。db query が終了した後に起動されるコールバック関数以外は何も繰り返されません。

database.query("SELECT * FROM table", function(rows) {
  var result = rows;
});

よろしければ、ご意見とご回答を聞かせてください。

4

2 に答える 2

9

あなたのロジックは正しいです。2 番目のイベントが待機します。そして、キューに入れられたコールバックの時間が来るまで実行されます。

また、技術の世界では「同時に」というものは存在しないことを忘れないでください。すべてのものには、非常に特定の場所と時間があります。

node.js が数千の接続を管理する方法は、ロジックをブロックしているデータベース呼び出しがある間、または別の IO 操作が処理されている間 (ストリームなど)、スレッドのアイドル状態を保持する必要がないことです。最初のリクエストを「処理」し、さらにコールバックを作成して、他のリクエストに進むことができます。
実行をブロックする方法がないため (無意味な while(true) などを除いて)、アプリケーション ロジック全体に実際のリソースを分散するのに非常に効率的になります。

スレッド - コストが高く、スレッドのサーバー容量は利用可能なメモリに直接関係しています。そのため、従来の Web アプリケーションのほとんどは、データベース クエリ ブロックが進行中または同様の処理が行われている間、単純にアイドル状態のスレッドで RAM が使用されるという理由だけで問題を抱えていました。ノードではそうではありません。

それでも、複数のスレッドを (child_process として) を介して作成できるため、cluster可能性がさらに広がります。

2 に答えてください。あなたが考えるかもしれない「ループ」のようなものはありません。接続や受信データなどがあるかどうかをチェックする舞台裏のループはありません。最近では、Async メソッドによっても処理されます。

したがって、アプリケーションの観点からは「メイン ループ」はなく、開発者の観点からはすべてがイベント ドリブンです (イベント ループではありません)。

の場合、http.createServerコールバックをリクエストへのレスポンスとしてバインドします。すべてのソケット操作と IO は、HTTP ハンドシェーク、ヘッダーの解析、クエリ、パラメーターなどと同様に、舞台裏で行われます。舞台裏で発生し、ジョブが完了すると、データが保持され、コールバックがイベント ループにプッシュされます。イベント ループが解放されると、node.js アプリケーション コンテキストでバックグラウンドからのデータを使用してコールバックが実行されるようになります。

データベース要求あり - 同じ話。データベースが応答するとコールバックし、データがアプリケーションコンテキスト用に準備されます。

正直なところ、node.js で必要なのは概念を理解することだけであり、イベントの実装は必要ありません。そして、それを行う最善の方法は実験です。

于 2013-07-11T00:06:12.973 に答える
1

1)はい、その通りです。

ノードで行うことはすべて主にI / Oバウンドであるため、機能します。

新しいリクエスト (イベント) が来ると、キューに入れられます。初期化時に、ノードは、ネットワーク/ソケット呼び出し、データベースなどのような I/O バウンド処理用のスレッドを生成する責任を負う ThreadPool を割り当てます (これはノンブロッキングです)。

これで、「コールバック」(またはイベント ハンドラー) は非常に高速になりました。これは、実行していることのほとんどが CRUD および I/O 操作であり、CPU を集中的に使用していない可能性が高いためです。

したがって、これらのコールバックは並行して処理されているように見えますが、実際にはそうではありません。実際の並行作業は ThreadPool を介して (マルチスレッドで) 行われているのに対し、コールバック自体は結果を受け取っているだけだからです。これらのスレッドから処理を続行して、クライアントに応答を返すことができるようにします。

これは簡単に確認できます。コールバックが負荷の高いCPU タスクである場合、1 秒あたり数千のリクエストを処理できず、マルチスレッド システムと比較して大幅にスケールダウンすることは確実です。

2)その通りです。

残念ながら、これらすべての抽象化により、バックグラウンドで何が起こっているかを理解するには、ダイビングする必要があります。ただし、はい、ループがあります。

特に Nodejs はlibuvで実装されています。

読んで面白い。

しかし、次のコードをイベント ドリブンかイベント ループかを識別する方法がわかりません。db query が終了した後に起動されるコールバック関数以外は何も繰り返されません。

イベント ドリブンとは、イベント ループがある場合に通常使用する用語で、ボタンのクリックやデータの到着などのイベントによって駆動されるアプリを意味します。通常、そのようなイベントにはコールバックを関連付けます。

于 2017-03-18T15:24:02.660 に答える