web-dev-qa-db-ja.com

node.jsが非同期なのはなぜですか?

実際にこれを尋ねた人はいません(私が得ているすべての「提案」から、またここで尋ねる前に検索することから)。

では、なぜnode.jsは非同期ですか?

私がいくつかの研究の後に推測したことから:

PHPおよびPython)はスクリプト言語です(スクリプト言語である実際の言語については間違っている可能性があります)が、JavaScriptはそうではありません。 JSがコンパイルされないという事実に由来しますか?)

Node.jsは単一のスレッドで実行され、スクリプト言語は複数のスレッドを使用します。

非同期とはステートレスであり、接続は永続的であり、同期は(ほぼ)反対であることを意味します。

答えは上記のどこかにあるかもしれませんが、私にはまだわかりません。

このトピックに関連する私の2番目と最後の質問は次のとおりです。

JavaScriptを同期言語にできますか?

PS。私はあなたの何人かが「なぜあなたはJSを同期させたいと思うだろうか?あなたの答えで、しかし真実は私がしないということです。私はこの種の質問をしているだけです。なぜなら、私自身だけでなく、そのような質問について考えた人がもっといると確信しているからです。

47
Joe

Node.jsは単一のスレッドで実行され、スクリプト言語は複数のスレッドを使用します。

技術的にではありません。 Node.jsは複数のスレッドを使用しますが、実行スレッドは1つだけです。バックグラウンドスレッドは、IOを処理して非同期のすべての機能を動作させるためのものです。スレッドを効率的に処理することは非常に苦痛です。バックグラウンドスレッドがIOでブロックされている間に実行します。

非同期とはステートレスであり、接続は永続的であり、同期は(ほぼ)反対であることを意味します。

必ずしも。非同期システムの状態を非常に簡単に保存できます。たとえば、Javascriptでは、bind()を使用してthisを関数にバインドし、関数が返されるときに状態を明示的に保持できます。

function State() {
    // make sure that whenever doStuff is called it maintains its state
    this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};

非同期とは、操作の完了を待たずに、リスナーを登録することを意味します。これは、他の言語、特にユーザーからの入力を受け入れる必要があるすべての言語で常に発生します。たとえば、Java GUIでは、ユーザーがボタンを押すのを待つことはできませんが、リスナーをGUIに登録します。

このトピックに関連する私の2番目と最後の質問は次のとおりです。

JavaScriptを同期言語にできますか?

技術的には、すべての言語は同期的であり、Javascriptさえもです。ただし、Javascriptはシングルスレッドになるように設計されているため、非同期設計では非常にうまく機能します。

基本的に、2種類のプログラムがあります。

  • CPUバウンド-高速化する唯一の方法は、CPU時間を増やすことです
  • IOバウンド-データの待機に多くの時間を費やすため、より高速なプロセッサは重要ではありません

ビデオゲーム、ナンバークランチャー、およびコンパイラはCPUバウンドですが、WebサーバーとGUIは一般的にIOバウンドです。Javascriptは(複雑さのため)比較的遅いため、できません。 CPUバウンドシナリオで競争するために(私を信じて、CPUバウンドJavascriptのかなりの部分を書きました)。

Javascriptは、クラスやオブジェクトの観点からコーディングする代わりに、一緒に結合できる単純な関数の観点からコーディングするのに適しています。これは非同期設計で非常にうまく機能します。これは、アルゴリズムを入力してデータをインクリメンタルに処理できるためです。IO(特にネットワークIO)は非常に遅いため、パケット間にかなりの時間があります。データの。

1000のライブ接続があり、それぞれがミリ秒ごとにパケットを配信し、各パケットの処理に1マイクロ秒かかると仮定します(非常に合理的です)。また、各接続が5パケットを送信すると仮定します。

シングルスレッドの同期アプリケーションでは、各接続は連続して処理されます。合計所要時間は(5 * 1 + 5 * .001)* 1000ミリ秒、または〜5005ミリ秒です。

シングルスレッドの非同期アプリケーションでは、各接続は並行して処理されます。各パケットには1ミリ秒かかり、各パケットの処理には.001ミリ秒かかるため、パケット間のすべての接続のパケットを処理できるので、式は1000 * .001 + 5 * 1ミリ秒、または約6ミリ秒になります。

この問題に対する従来の解決策は、より多くのスレッドを作成することでした。これでIO問題が解決しましたが、接続数が増えると、メモリ使用量(スレッドは多くのメモリを消費します)とCPU使用量(1コアに100スレッドを多重化するのは1より難しくなります) 1コアのスレッド)。

ただし、欠点もあります。 Webアプリケーションで重い数値演算を行う必要がある場合は、SOLになります。数値を演算している間は接続を待機する必要があります。OSがスワップアウトできるため、スレッド化はこれを解決します。 IOで待機するスレッドの準備ができているときにCPU集中型のタスクを実行します。また、node.jsは単一のコアにバインドされているため、複数のインスタンスとプロキシ要求をスピンアップしない限り、マルチコアプロセッサを利用できません。 。

51
beatgammit

Javascriptは何にもコンパイルされません。 PHP&Rubyのように、実行時に「評価」されます。したがって、PHP/Rubyのようなスクリプト言語です(正式名称は実際にはECMAScriptです)。

Nodeが順守する「モデル」は、PHP/Rubyとは少し異なります。Node.jsは、ネットワークリクエストを取得するという1つの目標を持つ「イベントループ」(単一スレッド)を使用します。それらを非常に迅速に処理し、何らかの理由でしばらく時間がかかる操作(API要求、データベースクエリ-基本的にIO(入力/出力)を含むもの)に遭遇した場合、それをバックグラウンドの「ワーカー」スレッドに渡し、オフになりますワーカースレッドが長いタスクの完了を待機している間に何か別のことを行うと、メインの「イベントループ」が結果を取得して処理を続行します。

スレッドモデルに従うPHP/Ruby。基本的に、すべての着信ネットワーク要求に対して、アプリケーションサーバーは、孤立したスレッドまたはプロセスを起動して要求を処理します。これは非常にうまくスケーリングされず、Nodeのアプローチは、このモデルと比較したコアの強みの1つとして挙げられています。

非同期とはステートレスであり、接続は永続的であり、同期は(ほぼ)反対であることを意味します。

いいえ。同期命令は最初から最後まで自然な順序で完了します。非同期命令とは、プログラムのフローのステップに比較的長い時間がかかる場合、プログラムは操作の実行を継続し、完了すると単にこの操作に戻ることを意味します。

JavaScriptを同期言語にできますか?

JavaScriptの特定の操作は同期的です。その他は非同期です。例えば:


ブロック操作:

for(var k = 0; k < 1; k = k - 1;){
  alert('this will quickly get annoying and the loop will block execution')
alert('this is blocked and will never happen because the above loop is infinite');

非同期:

jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); });
alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.');
32
Casey Flynn

JavaScriptを同期言語にできますか?

Javascriptは「非同期言語」ではありません。むしろ、node.jsには多くの非同期APIがあります。非同期性は、言語ではなくAPIのプロパティです。 javascriptで関数を簡単に作成して渡すことができるため、コールバック関数を渡すのが便利になります。これは非同期APIで制御フローを処理する1つの方法ですが、本質的に非同期のjavascriptはありません。 Javascriptは同期APIを簡単にサポートできます。

Node.jsが非同期なのはなぜですか?

Node.jsはシングルスレッドであるため、非同期APIを好みます。これにより、独自のリソースを効率的に管理できますが、長時間実行される操作は非ブロッキングである必要があり、非同期APIは多くの非ブロッキング操作でフローを制御できる方法です。

20
Trevor Dixon