2016-04-08 6 views
19

私は最近、Node.jsのコアについて多くの研究をしています.Nodeプラットフォームの内部動作についていくつか質問があります。私の理解では、Node.jsのは、次のように動作します。Node.jsで非同期のJavaScriptがどのように解釈されて実行されるのですか?

enter image description here

ノードは、プログラマが、ファイルシステムやネットワークのようなものと対話することができますJavaScriptで書かれたAPIを有しています。しかし、その機能はすべてC/C++コードで実際に行われ、Nodeの一部でもあります。ここで物事が少し曖昧になるところです。それで、javascriptを基本的に "コンパイル"(解釈?)することは、Chrome V8エンジンの仕事です。 V8はC++で書かれており、Javascript言語自体はECMAによって指定されているため、言語のキーワードや機能などはそれらによって定義されます。これが私の最初のいくつかの質問に私をリード:

ノードバインディングは、C++で書かれているので、ノード標準ライブラリは、ノードバインディングと相互作用することができる方法
  1. Chrome V8エンジンは、ノードのコンテキストでJavascriptをどのように解釈しますか?私はそれが同様の質問で言及されたJITというテクニックを使用していることを知っています:(https://softwareengineering.stackexchange.com/questions/291230/how-does-chrome-v8-work-and-why-was-javascript-not-jit-compiled-in-the-first-pl) しかしこれはJavascriptがNodeのコンテキストでどのように解釈されるか説明しません。ノード搭載のChrome V8エンジンは、Chromeブラウザ上で動作するエンジンとまったく同じエンジンであるのか、またはノードで動作するように変更されていますか?

これは私の次の質問につながります。ノードはイベント駆動のノンブロッキングIOを備えています。 Event Loopは、Node Event Loopと呼ばれることもありますが、実際には非同期IOを提供するように設計されたC++ライブラリであるlibuvライブラリの一部です。高レベルでは、イベントループは基本的にネイティブのJavascript機能であり、JavascriptがNodeプロジェクトの言語として選択された理由の1つであるコールバックを介してアクセスされます。これはまた、この小ぎれいなサイトでライブを実証することができ

enter image description here

:下記のイベントループがどのように動作するかの説明図であるhttp://latentflip.com/loupe/ は、私たちのノード・アプリケーションが外部APIへの呼び出しを行う必要があるとしましょう。だから我々はこれを書い:それは要求操作が終了するまで保持された場合、request

request(..., function eyeOfTheTiger() { 
    console.log("Rising up to the challenge of our rival"); 
}); 

当社のコールは、コールスタックにプッシュされます、そして私たちのコールバックがどこかに渡されます。実行されると、コールバックがコールバックキューに渡されます。コールスタックがクリアされるたびに、イベントループはコールバックキューの一番上にあるアイテムをコールスタックにプッシュし、そこで実行されます。このイベントループは、単一スレッドで実行されます。問題が発生するのは、誰かが「ブロッキング」コード、またはコールスタックを離れずにスレッドを効果的に結び付けるコードを書くときです。コールスタック上で常にコードが実行されている場合、イベントループはアイテムをコールバックキューからコールスタックにプッシュしないため、決して実行されず、基本的にアプリケーションをフリーズします。

  1. JavascriptがChrome V8エンジンによって解釈される場合、コードをコールバックキューにプッシュすることを「制御する」ものではないのですか? libuvイベントループによってJavascriptコードはどのように処理されますか?

私は、プロセスのデモンストレーションとして、この画像を見つけた:

enter image description here

私は正確にどのようにクロームV8エンジンとlibuvの相互作用についての不確実だところです。私はノードバインディングがこの相互作用を促進すると信じる傾向がありますが、どのようにすればよいかわかりません。上記の画像では、NodeJSバインディングがV8によってJavascriptからコンパイルされたマシンコードとのみ対話しているように見えます。もしそうなら、V8エンジンがJavascriptをどのように解釈してノードバインディングがコールバックと実際のコードをすぐに実行できるかを区別できるように混乱しています。

これは非常に深く複雑な一連の質問ですが、これはNode.jsを理解しようとしている人たちの多くの混乱を解消するのに役立ち、プログラマーにも利点と欠点を理解させるのに役立つと思います。より基本的なレベルでのイベント駆動のノンブロッキングIO

ステータスアップデート:ちょうどSenchaの会議(Link here)からの素晴らしい話を見ました。この話では、プレゼンターがV8埋め込みガイド(Link here)について言及し、C++の機能がJavascriptにどのように公開されるのか、その逆について話します。基本的にどのように動作するかは、C++の機能をV8に公開し、そのオブジェクトをJavascriptに公開する方法を指定し、V8インタプリタは組み込みのC++関数を認識して、それに一致するJavascriptを見つけたら実行できます。あなたが指定した。たとえば、実際にC++で記述された変数や関数をV8に公開することができます。これは本質的にNode.jsの機能です。 requireのような関数をJavascriptに追加することができます。この関数は、呼び出されたときに実際にC++コードを実行します。これにより、質問番号1は少しクリアされますが、ノード標準ライブラリがV8と連動してどのように動作するかは正確には示されません。 libuvがこれとどのように相互作用しているかについてはまだ不明です。

+1

あなたの質問にお答えしようとすると、私はあなたが探しているものはこれだと信じています - https://developers.google.com/v8/embed#templates。基本的には、すべてのC++コードをV8 VM内から呼び出せるJavaScript関数として公開します。 C++コールバックは、「アクセサ」コールバックと呼ばれるものを使用して定義できます。これは、コードのオブジェクトの特定のプロパティにアクセスするたびに呼び出されます。このすべてを説明する非常に良い記事があります - https://medium.com/@ghaiklor/how-nodejs-works-bfe09efc80ca#.xe4euk396 – booleanhunter

+0

素晴らしいリソース。あなたは賞金を得るために正式な答えを書いていますか? –

+0

私はリソースのことをやってみることはしていないので、まずそれをやるつもりだし、私の答えをより詳細なものに編集し直します。 – booleanhunter

答えて

12

基本的にお探しのものはV8 Templatesです。これは、すべてのC++コードをV8仮想マシン内から呼び出せるJavaScript関数として公開します。関数が呼び出されるとき、または特定のオブジェクトプロパティにアクセスするときに、C++コールバックを関連付けることができます(Read AccessorsおよびInterceptors)。

このすべてを説明する非常に良い記事が見つかりました。How does NodeJS work?です。また、非同期性を実現するためにlibuvがNodeと連携してどのように動作するかについても説明します。

希望すると便利です。

関連する問題