nodejsjavascript
non-blocking是指node.js进程中不一样步等待执行非javascript操做
(例如I/O)完成而继续执行下一块代码的特性。java
注:CPU密集型属于javascript操做。node
I/O一般指与磁盘
与网络
的交互linux
非阻塞I/O模型使得nodejs支持高并发且很是适合于I/O密集型应用c++
共6个阶段git
timers
setTimeout与setInterval回调函数队列pending callbacks
会在下一次loop中执行的系统级回调队列。如TCP ECONNREFUSED -idle,prepare
内部使用poll
接收新的I/O事件。执行I/O相关回调。在这个阶段node进程可能会阻塞check
setImmediate回调会在这个阶段执行close
一些关闭的回调。好比connect.on('close', () => {....})
注:process.nextTick不属于任何一个阶段,它是介于任意两个阶段之间,而且在阶段切换时执行nextTick回调github
注:所以nodejs并非纯粹的单线程语言!正则表达式
同步
执行常规的变量、方法的定义与调用,javascript全部回调以及非阻塞异步I/O如网络I/O异步
执行“昂贵”繁重的任务。node提供非阻塞I/O(操做系统不提供)API,以及CPU密集的I/O API
抽象来讲,Event Loop维护挂起事件的队列,Worker Pool维护挂起任务的队列。npm
实际上,Event Loop并非维护一个队列。而是一个文件描述符的集合
,这些文件描述符从系统级事件通知机制获取好比epoll(linux),kqueue(OSX),IOCP(Windows)。这些文件描述符对应于某些网络套接字以及node正在监视的文件等等。当某个描述符准备好时,Event Loop会将其转换为合适的事件并执行对应的回调。数组
另外,Worker Pool维护的是一个真正的队列。Worker会pop出队列的task并执行,完成后会触发Event Loop“至少一个事件已完成”的事件。
nodejs默认的Worker Pool专门用于处理I/O任务,维护本身的线程池可使用cluster模块以及child_process模块作自定义线程池。
Node服务器的吞吐量取决于
WorkerPool的吞吐量。有效下降逐个任务时间开销
以及稳定任务时间开销的变化
将最大程度提高服务器的吞吐量。最多见的方法就是复杂重复型任务(好比数组迭代)作分区处理。
注:因为调度Worker Pool会增长额外的通讯开销,由于Worker Pool没法获取主线程的命名空间从而没法直接读取Javascript对象,因此须要序列化/反序列化致使增长通讯成本。
npm生态系统中存在数十万个模块为开发者提供了极大的便利,然而社区中npm包参差不齐,由于没法较为准确的估计其使用Event Loop或者Worker Pool的成本而致使一些程序隐患。