编程语言爱好者程序员

Nodejs Event Loop

2019-03-28  本文已影响4人  赵阳_c149

Nodejs Event Loop

什么是Nodejs

Node.js 是一个javascript runtime 环境。在Node.js出现之前,Browser是最常用的javascript runtime环境。不同于Browser,Node.js通常用于开发服务器端的app。但是从底层来看,他们都是运行在V8 runtime engine上的。V8 runtime engine读取javascript 代码,并把javascript代码转为更快的机器代码。通过将JRE和Node.js进行比较,以更好的理解Node.js。

javascript runtime 的内存原理

在说明javascript是如何实现异步之前,先来看一下javascript runtime是如何进行内存管理的。在javascript runtime中,有堆栈(stack)和堆(heap)。一次方法调用将在堆栈中压入一个帧(frame),这个帧包括了方法的参数和本地参数。例如假设方法a调用方法b,则方法a和它的参数以及本地参数作为第一个帧入栈,然后b入栈。当b返回的时候,b先出栈,a再出栈。在程序执行的过程中创建的object是在堆上分配的,object的引用可以作为方法的参数或者本地参数出现在堆栈中。堆栈和堆的概念与java中的极为相似。更详细的内容可以参考相关文献。与java不同,javascript runtime还维护着第三类内存空间,队列(Queue)。队列中存放着一个消息的列表,所以该队列又叫消息队列。每个消息都有一个相关联的方法,在处理消息的时候这些方法将被依次调用。当与消息关联的方法被调用的时候,无一例外,也要在堆栈中压入一个帧。

javascript的异步实现

从本质上说,Javascript是“单线程”的,但并不意味着javascript不支持异步。事实上,javascript是通过event loop来实现异步的。Javascript runtime在运行的过程中,会通过调用一些由Node.js (或者Browser)提供的API(比如setTimeout)触发异步操作,并按照一定的规则将操作作为消息依次放入消息队列。异步操作通常包括一个回调函数(callback),当堆栈为空的时候,消息队列上的消息将被依次处理,也就是说,callback函数将以堆栈上的帧的方式被依次调用。

1. main()被推入Call Stack
2. console.log()被推入Call Stack。
3. setTimeout(2000)被推入Call Stack。setTimeout是一个Node API,当他被调用的时候,一个event-callback对被注册。这个event将等待2000 milliseconds,然后call back被加到Callback Queue中。
4. 注册完之后,setTimeout(2000)被弹出堆栈。
5. 然后,第二个setTimeout(0)以同样的方式注册。现在,我们有两个Node API 等待着被执行。 
6. 0 秒之后,setTimeout(0)被移动到callback queue(也就是消息队列)中;同样,2000 millisecond后,setTimeout(2000)也被移动到callback queue中。
7. 在callback queue中的方法等待call stack变空。这一过程由event loop控制。 
8. 最后一个console.log()执行,之后main被弹出call stack。
9. event loop 看到call stack为空,且callback queue不为空,这时,event loop会把callback(FIFO顺序)移动到call stack以使得这些方法被执行。

Nodejs event loop

Node.js沿用了javascript的eventloop机制。Node.js启动之后,会初始化eventloop,处理传入的javascript。这些javascript可能会进行async API调用,schedule timer等异步操作。并且Event loop将event loop分成了多个顺序相连的phase。在不同的phase中对不同类型的事件进行处理。例如在pollphase,主要接受外部的connection和request(I/O),并处理相关的callback。在timers phase处理由setTimeout和setInterval安排(schedule)的callback。

References

https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop#Visual_representation

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop

https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5

https://nodejs.org/docs/latest/api/events.html#events_emitter_setmaxlisteners_n

上一篇下一篇

猜你喜欢

热点阅读