node.js全局对象
需要注意的是,有一些变量,看起来是全局的,其实是每个模块内部的变量像:
进程对象
process是一个全局变量,即global对象的属性,它用于描述当前nodejs进程状态的对象,提供一个与操作系统的简单接口,通常在你写本地命令程序的时候使用:
process.stdin.resume();
process.stdin.on('data',function(data){
process.stdout.write('从控制台读入用户输入的字符'+data.toString());
});
events模块
Events模块是node.js对发布订阅模式的部署,一个对象通过这个模块向另一个对象传递消息,该模块通过EventEmitter属性,提供了一个构造函数,该构造函数的实例具有on方法,可以用来监听指定的事件,并触发回调函数,任意对象都可以发布指定事件,被EventEmitter实例的on方法监听到。
下面是一个实例,先建立一个消息中心,然后通过on方法,为各种事件指定回调函数,从而将程序志为事件驱动型,各个模块之间通过事件联系:
var EventEmitter = require("events").EventEmitter;
var ee = new EventEmitter();
ee.on("someEvent", function () {
console.log("event has occured");
});
ee.emit("someEvent");
上面代码在加载events模块后,通过EventEmitter属性建立了一个EventEmitter对象实例,这个实例就是消息中心。然后,通过on方法为someEvent事件指定回调函数。最后,通过emit方法触发someEvent事件。
Stream
Unix操作系统从很早以前,就有Stream(流)这个概念,它是不同进程之间传递数据的一种方式。管道命令Pipe就起到在不同命令之间,连接Stream的作用。
Stream把较大的数据,拆成很小的部分。只要命令部署了Stream接口,就可以把一个流的输出接到另一个流的输入。Node引入了这个概念,通过Stream为异步读写数据提供的统一接口。无论是硬盘数据、网络数据,还是内存数据,都可以采用这个接口读写。
读写数据有两种方式。一种方式是同步处理,即先将数据全部读入内存,然后处理。它的优点是符合直觉,流程非常自然,缺点是如果遇到大文件,要花很长时间,可能要过很久才能进入数据处理的步骤。另一种方式就是Stream方式,它是系统读取外部数据实际上的方式,即每次只读入数据的一小块,像“流水”一样。所以,Stream方式就是每当系统读入了一小块数据,就会触发一个事件,发出“新数据块”的信号,只要监听这个事件,就能掌握进展,做出相应处理,这样就提高了程序的性能。
Stream接口最大特点就是通过事件通信,具有readable、writable、drain、data、end、close等事件,既可以读取数据,也可以写入数据。读写数据时,每读入(或写入)一段数据,就会触发一次data事件,全部读取(或写入)完毕,触发end事件。如果发生错误,则触发error事件。
一个对象只要部署了Stream接口,就可以从读取数据,或者写入数据。Node内部很多涉及IO处理的对象,都部署了Stream接口,比如HTTP连接、文件读写、标准输入输出等。
Node.js 事件循环
Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。 Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。 Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。 Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.
事件驱动程序
Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。 当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。 这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO) 在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。 整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。 Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例: 给一个按钮绑定一个点击事件,当点击之后回调回调函数。
// 引入events模块
var events = require('events');
// 创建按钮对象
var button = new events.EventEmitter();
// 绑定事件及事件的处理程序
button.on('click', function(){console.log('点击了按钮');});
// 触发事件
button.emit('click');