//node 核心内置类库
//node 的核心模块有: EventEmitter, Stream, FS, Net 和全局对象
//------------------------------------------------------------------------------------------------------
//1.关于全局对象的介绍:
//(全局对象 有:process, console, Buffer和exports)
//全局对象的方法
//node中的事件循环:
// event loop其实就是一个事件队列,先加入先执行,执行完一次队列,再次循环遍历看有没有新事件加入队列.
// 执行中的叫IO events, setImmediate是在当前队列立即执行,setTimout/setInterval是把执行定时到下一个队列,
// process.nextTick是在当前执行完,下次遍历前执行.
// 所以总体顺序是: IO events >> setImmediate >> setTimeout/setInterval >> process.nextTick
//------------------------------------------------------------------------------------------------------
//2.核心模块
//核心模块 EventEmitter 是在node中实现观察者模式的类,主要功能是监听和发射消息,用于处理多模块交互的问题。
//如何实现一个EventEmitter?
//require('express'); 测试require的代码
//------
//let 块级作用域,防止重定义。
//在JS函数中的var声明,其作用域是函数体的全部
//const a = {a:'a'};-->绑定的是对象指针
////重新赋值当然是行不通的了
//a = {a:'b'};-->绑定新对象的指针
////并不是科技
//a.a = 'b' -->对象指针没变,指针指向的内容可以随意改变。
//------
'use strict' //严格模式
let util = require('util'); //工具类
let EventEmitter = require('events').EventEmitter
//构造函数
function MyEmitter(){
EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter); // 继承
let em = new MyEmitter();
em.on('hello', function(data) {
console.log('收到事件hello的数据:', data);
}); // 接收事件,并打印到控制台
em.emit('hello', 'EventEmitter传递消息真方便!');
//父类
let father = new EventEmitter();
father.on('hello', function(data){
console.log('收到数据是:', data)
})
father.emit('hello', 'alibaba');
//domain模块可以用来统一处理错误事件
const domain = require('domain');
const myDomain = domain.create();
myDomain.on('error', function (data) {
console.log("domain 接收到错误的事件了 "+ data);
})
myDomain.run(function () {
var myEmitter1 = new MyEmitter();
myEmitter1.emit('error', '立即执行来自myEmitter1的错误事件');
var myEmitter2 = new MyEmitter();
myEmitter2.emit('error', '立即执行赖子myEmitter2的错误事件');
});
//上述EventEmitter 典型应用是:
//参考答案: 1) 模块间传递消息 2) 回调函数内外传递消息 3) 处理流数据,因为流是在EventEmitter基础上实现的. 4) 观察者模式发射触发机制相关应用
//EventEmitter中的newListenser事件有什么用处?
//newListener可以用来做事件机制的反射,特殊应用,事件管理等.当任何on事件添加到EventEmitter时,就会触发newListener事件,基于这种模式,我们可以做很多自定义处理.
// 代码演示
var emitter3 = new MyEmitter();
emitter3.on('newListener', function(name, listener) {
console.log("新事件的名字:", name);
console.log("新事件的代码:", listener);
setTimeout(function(){ console.log("我是自定义延时处理机制"); }, 1000);
});
//没有 使用enitter3.emit 发消息, 而是emitter3.on事件添加到EventEmitter时,就会触发newListener事件。
emitter3.on('hello', function(data){
console.log('hello node' + data);
});
emitter3.emit('hello', "testtest112233")
//Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。
//Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,
// 每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.
//事件驱动程序
//Node.js 使用事件驱动模型,
// 当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
// 当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
// 这个模型非常高效可扩展性非常强,因为web server一直接受请求而不等待任何读写操作。
// (这也被称之为非阻塞式IO或者事件驱动IO)。
// 在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例:
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
以下程序绑定事件处理程序:
var eventHandler = function(){
console.log("--eventName rec----");
}
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);
我们可以通过程序触发事件:
// 触发事件
eventEmitter.emit('eventName');