Comment est javascript asynchrone interprété et exécuté dans le noeud.js?

j'ai fait beaucoup de recherches sur le noyau de Node.js dernièrement, et j'ai quelques questions sur le fonctionnement interne de la plateforme de noeuds. Comme je le comprends, Nœud.js travaille comme ceci:

enter image description here

Node a une API, écrite en Javascript, qui permet au programmeur d'interagir avec des choses comme le système de fichiers et le réseau. Cependant, toute cette fonctionnalité est en fait faite par le code C / C++ , aussi une partie du noeud. Voici où les choses deviennent un peu floue. C'est donc le travail du moteur V8 de Chrome de "compiler"essentiellement(interpréter? javascript vers le bas dans le code machine. V8 est écrit en C++, et le langage Javascript lui-même est spécifié par ECMA, de sorte que des choses telles que les mots-clés et les caractéristiques du langage sont définis par eux. Cela m'amène à mes premières questions:

  1. comment la bibliothèque standard des noeuds peut-elle interagir avec les reliures des Noeuds?, puisque les reliures de noeuds sont écrites en C++?

  2. comment le moteur Chrome V8 interprète Javascript dans le contexte de Node? Je sais qu'il utilise une technique appelée JIT, qui a été mentionnée dans une question similaire: ( https://softwareengineering.stackexchange.com/questions/291230/how-does-chrome-v8-work-and-why-was-javascript-not-jit-compiled-in-the-first-pl ) Mais cela n'explique pas comment Javascript est interprété dans le contexte de Nœud. Est-ce que le moteur Chrome V8 qui est livré avec Node est exactement le même que celui qui fonctionne sur le navigateur Chrome, ou a-t-il été modifié pour fonctionner avec Node?

cela m'amène à ma prochaine question. Ainsi, les caractéristiques du noeud sont fonction d'un événement, IO non-bloquant. Il y parvient via la boucle D'événement, qui, bien qu'elle soit souvent appelée "Boucle D'événement de Noeud", fait en fait partie de la bibliothèque libuv, une bibliothèque C++ conçue pour fournir des IO asynchrones. À un haut niveau, la boucle d'événement est essentiellement accessible via des Callbacks, qui est une fonctionnalité JavaScript native et L'une des raisons pour lesquelles Javascript a été choisi comme langue pour le projet de Noeud. Ci-dessous une illustration du fonctionnement de la boucle d'événement:

enter image description here

cela peut également être démontré en direct par ce petit site soigné: http://latentflip.com/loupe / Disons que notre application de Noeud il faut faire un appel à une API externe. Nous écrivons donc ceci:

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

notre appel à request est poussé sur la pile d'appels, et notre rappel est passé quelque part, où il est gardé jusqu'à la fin de l'opération de demande. Lorsque c'est le cas, le rappel est passé dans la file d'attente. Chaque fois que la pile d'appels est effacée, la boucle d'événement pousse l'élément en haut de la file d'attente de rappel sur la pile d'appels, où il est exécuté. Cette boucle d'événement est exécutée sur un seul fil. Lorsque des problèmes surgissent, c'est lorsque quelqu'un écrit du code "de blocage", ou du code qui ne quitte jamais la pile d'appels et qui bloque effectivement le thread. S'il y a toujours du code exécuté sur la pile d'appels, la boucle d'événement ne poussera jamais les éléments de la file d'attente de rappel sur la pile d'appels et ils ne seront jamais exécutés, bloquant essentiellement l'application. Ceci m'amène à ma question suivante:

  1. si le Javascript est interprété par le moteur Chrome V8, que qu'est-ce qui" contrôle " la mise de code sur la file d'attente de rappel? Comment le code Javascript est-il géré par la boucle d'événements de libuv?

j'ai trouvé cette image comme une démonstration du processus:

enter image description here

c'est là que je ne sais pas exactement comment le moteur V8 de Chrome et la libuv interagissent. Je suis enclin à croire que les reliures de Noeud facilitent cette interaction, mais je ne suis pas tout à fait sûr de savoir comment. Dans l'image ci-dessus, il apparaît que les liaisons NodeJS n'interagissent qu'avec du code machine qui a été compilé à partir de Javascript par V8. Si c'est le cas, je ne comprends pas comment le moteur V8 interprète le Javascript de telle manière que les reliures de Noeud puissent faire la différence entre le rappel et le code réel à exécuter immédiatement.

je sais qu'il s'agit d'une série de questions très profondes et compliquées, mais je crois que cela aidera à clarifier un beaucoup de confusion pour les gens qui essaient de comprendre Nœud.js, et aussi aider les programmeurs à comprendre les avantages et les inconvénients de l'événementiel, de la non-blocage de IO à un niveau plus fondamental.

mise à Jour de Statut: Juste regardé un fantastique de parler à partir d'un Sencha de la conférence( ici ). Ainsi, dans cette présentation, le présentateur mentionne le guide V8 embed ( lien ici ), et parle de la façon dont les fonctions C++ peuvent être exposé au Javascript et vice versa. Essentiellement, la façon dont cela fonctionne est que les fonctions C++ peuvent être exposées à V8 et aussi spécifier comment il veut que ces objets soient exposés à Javascript, et L'interpréteur V8 sera capable de reconnaître vos fonctions C++ intégrées et de les exécuter s'il trouve Javascript qui correspond à ce que vous avez spécifié. Par exemple, vous pouvez exposer des variables et des fonctions à V8 qui sont en fait écrites en C++. C'est essentiellement à ce Nœud.js; il est en mesure d'ajouter des fonctions comme require dans Javascript qui exécute le code C++ quand ils sont appelés. Cela clarifie un peu la question numéro 1, mais cela ne montre pas exactement comment la bibliothèque standard du noeud fonctionne en conjonction avec V8. Il n'est toujours pas clair non plus sur la façon dont libuv interagit avec tout cela.

22
demandé sur Community 2016-04-08 07:11:44

1 réponses

Fondamentalement, ce que vous cherchez est V8 Modèles . Il expose tout votre code C++ comme des fonctions JavaScript que vous pouvez appeler depuis la Machine virtuelle V8. Vous pouvez associer des callbacks C++ lorsque des fonctions sont invoquées ou lorsque des propriétés spécifiques d'un objet sont consultées (lisez et intercepteurs ).

j'ai trouvé un très bon article qui explique tout cela - Comment fonctionne NodeJS? . Il explique également comment libuv fonctionne en conjonction avec Node pour atteindre l'asynchronisme.

Espérons que cette aide!

13
répondu booleanhunter 2016-04-12 00:57:15