在 Java、PHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约 2MB 内存。也就是说,理论上,一个 8GB 内存的服务器可以同时连接的最大用户数为 4000 个左右。要让 Web 应用程序支持更多的用户,就需要增加服务器的数量,而 Web 应用程序的硬件成本当然就上升了。node.js 不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞 I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。使用 Node.js,一个 8GB 内存的服务器,可以同时处理超过 4 万用户的连接。

但是在实际过程中,非阻塞也会产生一定的问题,例如,我们需要从后台请求数据,然后拿到这些数据以后,执行某些操作,但是由于非阻塞,不能控制获取数据的时间,后续的操作就会出现问题。

在上面例子中,我们希望先执行第一个打印,然后执行文件读取,最后执行第四个打印。但是由于Node是非阻塞的,在执行到文件读取的时候,由于文件大小的原因,需要一定的时间,在这个时间里,有并行处理了第四个打印,等第四个打印执行了,前面的文件读取才执行结束,于是就有了下面的输出

同样,在下面的例子中,同样由于执行文件读取的时间过长,在读取文件的时候,并发执行了打印事件,所以打印的时候,并没有数据。

      

可是在实际项目中,这种结果是不能接受的,为了保证能打印出数据,我们希望在文件结束后,再执行打印事件,下面两种办法就是实现这个要求。

回调函数

   

event模块处理异步

Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件。

在使用events 模块的时候,需要先引入改模块,并创建 EventEmitter对象。

var events=require('events');
var EventEmitter=new events.EventEmitter();

然后在需要等待上面执行完毕再执行的事件里面,绑定事件和事件处理程序

eventEmitter.on('eventName', eventHandler);

最后,在处理费时程序的地方,触发上面的绑定

eventEmitter.emit('eventName');

绑定和触发的事件名称需要保持一致。

按照上面的方式,我们可以对前面的例子进行调整:

   

event模块

Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列,所有这些产生事件的对象都是 events.EventEmitter 的实例,EventEmitter 的核心就是事件触发与事件监听器功能的封装。EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。

基础用法

  

多个监听器

EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。

  

非阻塞I/O事件驱动的更多相关文章

  1. Node.js学习笔记(六) --- Nodejs 的非阻塞 I/O、 异步、 事件驱动

    1. Nodejs 的单线程 非阻塞 I/O 事件驱动在 Java. PHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程.而每个线程需要耗费大约 2MB 内存.也就是说,理论 ...

  2. (一) 这就是所谓的Node.js------单线程,非阻塞,事件驱动

    Node.js 第一天笔记(V1) 一:Node.js到底是从何而来 2008年的秋天,一个名叫做Ryan Dahl(罗伊・达尔)的年轻人在玩了几年服务器编程之后,越发感到服务器高并发性能的瓶颈是一个 ...

  3. 事件驱动模型 IO多路复用 阻塞IO与非阻塞IO select epool

    一.事件驱动 1.要理解事件驱动和程序,就需要与非事件驱动的程序进行比较.实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的.早期则存在许多非事件驱动的程序,这样的程序,在需要等待 ...

  4. 【Todo】React & Nodejs学习 &事件驱动,非阻塞IO & JS知识栈:Node为主,JQuery为辅,Bootstrap & React为辅辅,其他如Angular了解用途即可

    JS知识栈:Node为主,JQuery为辅,Bootstrap & React为辅辅,其他如Angular了解用途即可 今天在学习ReactJS和NodeJS,看到关于ReactJS的这篇文章 ...

  5. 【python】-- 事件驱动介绍、阻塞IO, 非阻塞IO, 同步IO,异步IO介绍

    事件驱动介绍 一.前言 通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求: (2)每收到一个请求,创建一个新的线程,来处理该请求: (3)每收 ...

  6. Nodejs 之非阻塞 I/O、异步、事件驱动

    1.非阻塞 I/O var fs = require('fs'); console.log('); fs.readFile('mime.json',function (err,data) {//rea ...

  7. 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO

    完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...

  8. 理解同步,异步,阻塞,非阻塞,多路复用,事件驱动IO

    以下是IO的一个基本过程 先理解一下用户空间和内核空间,系统为了保护内核数据,会将寻址空间分为用户空间和内核空间,32位机器为例,高1G字节作为内核空间,低3G字节作为用户空间.当用户程序读取数据的时 ...

  9. 同步异步,阻塞非阻塞 和nginx的IO模型

    同步与异步 同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication).所谓同步,就是在发出一个*调用*时,在没有得 ...

随机推荐

  1. java利用itext导出pdf

    项目中有一功能是导出历史记录,可以导出pdf和excel,这里先说导出pdf.在网上查可以用那些方式导出pdf,用itext比较多广泛. 导出pdf可以使用两种方式,一是可以根据已有的pdf模板,进行 ...

  2. webpos登录不上

    jo=new JSONObject(((java.sql.Clob)s).getSubString(1, (int) ((java.sql.Clob)s).length()));

  3. css设置文字多余部分显示省略号

    如果只显示一行,则可以使用以下方法: overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 如果需要显示多行,在需要设置的元素s ...

  4. kettle之linux使用kettle

    Kettle可以在Window.Linux.Unix上运行,数据抽取高效稳定,使用之前需要准备环境. 准备java环境,这里就不赘述了,建议jdk7以上版本. 上传kettle压缩包,并解压,我解压的 ...

  5. [ 随手记 5 ] C/C++ 继承

    个人理解: 继承:(意译)继续承接: A继承B,则A是派生类/子类,B为基类/父类: B有的成员变量/性质,A全部都有,而A有的B不一定有,在数学集合上可以说:B是A的子集: A继承B,可以说是A在B ...

  6. SQLI DUMB SERIES-19

    (1)根据题意,从Referer入手 (2)报错注入与上一关相同.如爆库名: 'and extractvalue(1,concat(0x7e,(select database()),0x7e)) an ...

  7. Spring ConditionalOnProperty

    Spring Annotation @ConditionalOnProperty spring doc解释 @Conditional: Indicates that a component is on ...

  8. RobotFramework-RIDE环境搭建二:Robot Framework-RIDE安装过程以及踩雷点

    前期准备工作: Python 2.7(上篇文章中已安装成功) Robot Framework-2.8.5 Robot Framework-RIDE-1.5.2.1 (测试用例的创建.运行可以在图形界面 ...

  9. What is the Annotation?

    Annotation称为注释或注解,它是一个接口.注解提供了一种为程序元素(类.方法.成员变量等)设置元数据(描述其它数据的数据)的方法.编译器.开发工具或其它程序中可以通过反射来获取程序中的Anno ...

  10. 使用Websocket与服务器建立连接

    handleMessage = () => { const url = '////'; //某url const token = getCookie('xnToken');//向后端发请求得登陆 ...