小结Node.js中非阻塞IO和事件循环_node.js

  学习和使用Node.js已经有两个月,使用express结合mongoose写了一个web应用和一套RESTful web api,回过头来看Node.js官网首页对Node.js的介绍:Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.那么其中的non-blocking I/O model 意味着什么呢?

非阻塞的IO模型

  首先,IO操作无疑是耗时的,当服务器端接收到大量请求时,为每一个请求创建进程或线程的同时,也增加了额外的内存开销,也可能浪费更多的时间资源。

  由于Node.js是事件驱动的,于是它使用了事件循环来解决IO操作带来的瓶颈问题。在Node.js中,一个IO操作通常会带有一个回调函数,当IO操作完成并返回时,就会调用这个回调函数,而主线程则继续执行接下来的代码。简单的用一个例子来说明这个问题:

request('http://www.google.com', function(error, response, body) {
   console.log(body);
});

console.log('Done!');

  这段代码的意思是向'http://www.google.com'发出请求,当请求返回这则调用回调函数输出响应信息。由于Node.js的运行机制,这段代码运行后,会立即在控制台输出'Done!',然后一段时间后再输出响应的信息。

事件循环 event loop

  接下来,来讨论下事件循环的机制。首先说说调用桟,比如有如下一段代码:

function A(arg, func){
  var a = arg;

  func();
  console.log('A');
}

function B(){
  console.log('B');
}

A(0, B);

  当代码执行后,函数A首先被推入调用桟中成为栈顶元素并开始执行A,在执行过程中函数B又被推入调用桟成为栈顶元素,在B执行完成后,B被弹出调用桟,A再次成为栈顶元素,在A执行完成后A被弹出调用桟,调用桟呈空闲状态。

  在Javascript运行时中存在一个消息队列,而消息和一个回调函数相关联,当一个事件被触发时,如果这个事件有相应的回调函数,则该消息就会被加入到消息队列中去。

  回过头来说事件循环到底循环的是什么,在代码开始执行后,函数被不断推入调用桟中,就拿上面的例子来讲,request被推入调用桟中,这个函数将进行一个http请求(这个http请求将交由Node.js的底层模块来实现)同时请求完成的事件和一个回调函数关联起来,request被弹出调用桟,console.log被推入调用桟开始执行。当请求完成时,完成事件被触发,一条消息被添加进消息队列中,消息队列首先会检查调用桟是否为空闲状态,如果调用桟并不空闲,则会一直等待到调用桟空闲状态后,将消息队列的头部弹出,此时与该消息相关联的回调函数被执行。

小结

  以上就无阻塞模型和事件循环在概念上进行了总结。而这个事件循环的机制并不仅仅是Node.js所独有的,并且Node.js的代码是单线程执行的,在面对大量并发请求的时候,又有着什么优势呢?

  上面这张图展示了Node.js的架构图,Node.js的底层有一个模块负责维护线程池,当一个IO请求发出的时候,Node.js的底层模块将新建一个线程来处理请求,完成后再将结果交还给上层。那么,当有多个请求的时候,Node.js的底层模块将利用尽可能少的线程来完成最多的任务,如果存在空闲的线程,它将继续被利用来做其他的事情,这对于前面说的针对每个请求开一个新的进程或线程而言,无疑“聪明”许多,也更加高效了。

  这篇文章是对学习Node.js的一个总结,其中若有问题和不足,欢迎批评指正。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索node.js
, 事件循环
非阻塞IO
nodejs 非阻塞io、nodejs 阻塞、nodejs 阻塞等待、node 阻塞、nodejs非阻塞,以便于您获取更多的相关知识。

时间: 2024-11-04 17:15:30

小结Node.js中非阻塞IO和事件循环_node.js的相关文章

Node.js 非阻塞IO和事件循环

非阻塞的IO模型 首先,IO操作无疑是耗时的,当服务器端接收到大量请求时,为每一个请求创建进程或线程的同时,也增加了额外的内存开销,也可能浪费更多的时间资源. 由于Node.js是事件驱动的,于是它使用了事件循环来解决IO操作带来的瓶颈问题.在Node.js中,一个IO操作通常会带有一个回调函数,当IO操作完成并返回时,就会调用这个回调函数,而主线程则继续执行接下来的代码.简单的用一个例子来说明这个问题: request('http://www.google.com', function(err

深入浅析Node.js 事件循环_node.js

Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. (来源于Javascript是单线程又是异步的,但是这种语言有个共同的特点:它们是 event-driven 的.驱动它们的 event 来自一个异构的平台.) Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发. Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现. Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件

我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环_node.js

一,node.js的作用, I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标移动,在屏幕上看到鼠标的移动.终端的输入,和看到的输出.等等)   node.js想解决的问题,(处理输入,输入,高并发 .如 在线游戏中可能会有上百万个游戏者,则有上百万的输入等等)(node.js适合的范畴:当应用程序需要在网络上发送和接收数据时Node.js最为适合.这可能是第三方的API,联网设备或者浏览器与服务器之间的实时通信)   并发的意义,(并发这个术语描述的

详解Node.js:events事件模块_node.js

Nodejs的大部分核心API都是基于异步事件驱动设计的,所有可以分发事件的对象都是EventEmitter类的实例. 大家知道,由于nodejs是单线程运行的,所以nodejs需要借助事件轮询,不断去查询事件队列中的事件消息,然后执行该事件对应的回调函数,有点类似windows的消息映射机制.至于更细的实现环节,可以另行查找资料. 下面介绍EventEmitter的使用. 1.监听事件和分发事件 EventEmitter实例可以使用on或addListener监听事件,emit()方法分发事件

Node.js的特点和应用场景介绍_node.js

Node.js应该是当今最火热的技术之一.本文主要介绍Node.js的特点及应用场景. Node.js是一个基于Chrome JavaScript运行时建立的一个平台,用来方便地搭建快速的 易于扩展的网络应用.Node.js借助事件驱动,非阻塞I/O模型变得轻量和高效,非常适合 运行在分布式设备的数据密集型实时应用. 1. 特点 1.1 异步I/O 所谓的异步I/O,是相对同步I/O而言的.程序执行过程中必然要进行很多I/O操作,如读写文件.输入输出.请求响应等等.通常来说,I/O操作是非常费时

node模块机制与异步处理详解_node.js

1.模块机制 commonJS模块机制出现的目的是为了构建js在web服务器,桌面程序,浏览器等方面形成生态系统.而node js就是这种规范的一种实现,用requird来引入其他文件,同样,npm也遵循了commonJS定义的包规范,从而形成了一套完整的生态系统. 模块定义并导出 例如有如下一个名为circle.js的文件 exports.getName = function(name) { return name } 模块载入 var circle = require('/circle.js

Node.js中的事件驱动编程详解_node.js

在传统程编程模里,I/O操作就像一个普通的本地函数调用:在函数执行完之前程序被堵塞,无法继续运行.堵塞I/O起源于早先的时间片模型,这种模型下每个进程就像一个独立的人,目的是将每个人区分开,而且每个人在同一时刻通常只能做一件事,必须等待前面的事做完才能决定下一件事做什么.但是这种在计算机网络和Internet上被广泛使用的"一个用户,一个进程"的模型伸缩性很差.管理多个进程时,会耗费很多内存,上下文切换也会占用大量资源,这些对操作系统是个很大的负担,而且随着进程数的递增,会导致系统性能

Node.js中的process.nextTick使用实例_node.js

我已经不记得是在哪里第一次看到process.nextTick这个玩意的调用了,哦,应该是在nodejs官方的process文档里看到的.当时就不理解这东西是干嘛的了,都已经有setTimeout了,还需要这个函数干嘛.而且从根本上来说,这个函数又是干嘛的?和setTimeout有什么区别? stackoverflow上有一个非常好的帖子基本上解释了我的问题,这里我附上链接,然后给出它里面的范例: stackoverflow.com >> What are the proper use cas

充分发挥Node.js程序性能的一些方法介绍_node.js

 一个Node.JS 的进程只会运行在单个的物理核心上,就是因为这一点,在开发可扩展的服务器的时候就需要格外的注意. 因为有一系列稳定的API,加上原生扩展的开发来管理进程,所以有很多不同的方法来设计一个可以并行的Node.JS运用.在这篇博文里,我们就来比较下这些可能的架构. 这篇文章同时也介绍compute-cluster 模块:一个小型的Node.JS库,可以用来很方便的管理进程,从来二线分布式计算. 遇到的问题 我们在Mozilla Persona的项目中需要可以处理大量不同特征的请求,