异步javascript如何在Node.js中解释和执行? [英] How is asynchronous javascript interpreted and executed in Node.js?

查看:194
本文介绍了异步javascript如何在Node.js中解释和执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在研究Node.js的核心,我对Node平台的内部工作有一些疑问。据我了解,Node.js的工作原理如下:





Node有一个用Javascript编写的API,它允许程序员与文件系统和网络之类的东西进行交互。但是,所有这些功能实际上都是由C / C ++代码完成的,也是Node的一部分。事情变得模糊不清。因此,Chrome V8引擎的工作基本上是编译(解释?)javascript到机器代码。 V8是用C ++编写的,而Javascript语言本身是由ECMA指定的,因此关键字和语言特征等都是由它们定义的。这引出了我的前几个问题:


  1. 节点标准库如何与节点绑定进行交互,因为Node Bindings是用C ++编写的吗?


  2. Chrome V8引擎如何在Node的上下文中解释Javascript?我知道它使用了一种名为JIT的技术,在类似的问题中提到过:(



    这也可以通过这个简洁的小网站现场演示:



    这是我不确定Chrome V8的确切位置的地方引擎和libuv交互。我倾向于相信节点绑定有助于这种交互,但我不太确定如何。在上图中,似乎NodeJS绑定仅与通过V8从Javascript编译的机器代码进行交互。如果是这样,我很困惑V8引擎如何以这样的方式解释Javascript,即Node Bindings可以区分回调和实际代码以立即执行。



    <我知道这是一个非常深刻和复杂的一系列问题,但我相信这将有助于为试图理解Node.js的人们解决很多困惑,并且还帮助程序员理解事件的优点和缺点 - 更基本的驱动,非阻塞IO。



    状态更新:刚观看Sencha会议的精彩演讲(此处链接)。因此,在本次演讲中,演示者提到了V8嵌入指南(此处链接),并讨论了如何C ++函数可以暴露给Javascript,反之亦然。本质上它是如何工作的是C ++函数可以暴露给V8并且还指定它希望这些对象如何暴露给Javascript,并且V8解释器将能够识别嵌入式C ++函数并在它找到与之匹配的Javascript时执行它们你指定了。例如,您可以将变量和函数公开给V8,这些变量和函数实际上是用C ++编写的。这基本上是Node.js的作用;它能够将诸如 require 之类的函数添加到Javascript中,这些函数在调用时实际执行C ++代码。这稍微清除了问题1,但它并没有准确地显示Node标准库如何与V8一起工作。关于libuv如何与其中任何一个进行交互仍然不清楚。

    解决方案

    基本上你要找的是 V8模板 。它将您的所有C ++代码公开为可以在V8虚拟机中调用的JavaScript函数。您可以在调用函数或访问特定对象属性时关联C ++回调(阅读 访问者 拦截器 )。



    我发现了一篇非常好的文章解释了所有这些 - NodeJS如何工作? 即可。它还解释了libuv如何与Node一起工作以实现异步性。



    希望这会有所帮助!


    I've been doing a lot of research into the core of Node.js lately, and I have some questions about the inner workings of the Node platform. As I understand it, Node.js works like this:

    Node has an API, written in Javascript, that allows the programmer to interact with things like the filesystem and network. However, all of that functionality is actually done by C/C++ code, also a part of Node. Here is where things get a little fuzzy. So it's the Chrome V8 engine's job to essentially "compile"(interpret?) javascript down into machine code. V8 is written in C++, and the Javascript language itself is specified by ECMA, so things such as keywords and features of the language are defined by them. This leads me to my first few questions:

    1. How is the Node Standard Library able to interact with the Node Bindings, since the Node Bindings are written in C++?

    2. How does the Chrome V8 engine interpret Javascript in the context of Node? I know it uses a technique called JIT, which was mentioned in a similar question: (https://softwareengineering.stackexchange.com/questions/291230/how-does-chrome-v8-work-and-why-was-javascript-not-jit-compiled-in-the-first-pl) But this doesn't explain how Javascript is interpreted in the context of Node. Is the Chrome V8 engine that ships with Node the exact same engine that runs on the Chrome browser, or has it been modified to work with Node?

    That brings me to my next question. So Node features event-driven, non-blocking IO. It accomplishes this via the Event Loop, which, although it is often referred to as the "Node Event Loop", is actually a part of the libuv library, a C++ library designed to provide asynchronous IO. At a high level, the event loop is essentially accessed via Callbacks, which is a native Javascript feature and one of the reasons Javascript was chosen as the language for the Node project. Below is an illustration of the how the event loop works:

    This can also be demonstrated live by this neat little site: http://latentflip.com/loupe/ Let's say our Node application needs to make a call to an external API. So we write this:

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

    Our call to request gets pushed onto the call stack, and our callback is passed somewhere, where it is kept until the request operation finishes. When it does, the callback is passed onto the callback queue. Every time the call stack is cleared, the event loop pushes the item at the top of the callback queue onto the call stack, where it is executed. This event loop is run on a single thread. Where problems arise is when someone writes 'blocking' code, or code that never leaves the call stack and effectively ties up the thread. If there is always code executing on the call stack, than the event loop will never push items from the callback queue onto the call stack and they will never get executed, essentially freezing the application. This leads me to my next question:

    1. If the Javascript is interpreted by the Chrome V8 engine, than what "controls" the pushing of code onto the callback queue? How is Javascript code handled by the libuv event loop?

    I've found this image as a demonstration of the process:

    This is where I'm uncertain about how exactly Chrome V8 engine and libuv interact. I'm inclined to believe that the Node Bindings facilitate this interaction, but I'm not quite sure how. In the image above, it appears as though the NodeJS bindings are only interacting with machine code that has been compiled down from Javascript by V8. If so, than I am confused as to how the V8 engine interprets the Javascript in such a way that the Node Bindings can differentiate between the callback and the actual code to immediately execute.

    I know this is a very deep and complicated series of questions, but I believe this will help to clear up a lot of confusion for people trying to understand Node.js, and also help programmers to understand the advantages and disadvantages of event-driven, non-blocking IO at a more fundamental level.

    Status Update: Just watched a fantastic talk from a Sencha conference(Link here). So in this talk, the presenter mentions the V8 embed guide(Link here), and talks about how C++ functions can be exposed to Javascript and vice versa. Essentially how it works is that C++ functions can be exposed to V8 and also specify how it wants those objects to be exposed to Javascript, and the V8 interpreter will be able to recognize your embedded C++ functions and execute them if it finds Javascript that matches what you specified. For example, you can expose variables and functions to V8 that are actually written in C++. This is essentially what Node.js does; it is able to add functions like require into Javascript that actually execute C++ code when they are called. This clears up question number 1 a little, but it doesn't exactly show how the Node standard library works in conjunction with V8. It is still also unclear about how libuv is interacting with any of this.

    解决方案

    Basically what you are looking for is V8 Templates. It exposes all your C++ code as JavaScript functions that you can call from within the V8 Virtual Machine. You can associate C++ callbacks when functions are invoked or when specific object properties are accessed (Read Accessors and Interceptors).

    I found a very good article which explains all of this - How does NodeJS work?. It also explains how libuv works in conjunction with Node to achieve asynchronicity.

    Hope this helps!

    这篇关于异步javascript如何在Node.js中解释和执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆