1.Node.js事件循环
- Node.js是单进程单线程应用程序,但因为V8引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。
- Node.js几乎每一个API都是支持回调函数的。
- Node.js基本上所有的事件机制都是用设计模式中观察者模式实现。
- Node.js单线程类似进入一个while(true)的事件循环,知道没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数。
2. 事件驱动程序
Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
3.使用
let events = require("events");
let ee = new events.EventEmitter();
ee.on("helloSuccess",function(eventMsg){
console.log("1");
console.log(eventMsg);
});
ee.on("helloSuccess",function(){
console.log("2");
});
ee.on("helloSuccess",function(){
console.log("3");
});
ee.on("helloSuccess",function(){
console.log("4");
});
async function test(){
let data = 'hello';
ee.emit("helloSuccess",data);
}
test();
// 结果
1
hello
2
3
4
4. 通过发布-订阅模式实现
let htEvent = {
event: {
// fileSuccess:[fn,fn,fn]
},
on: function (eventName, eventFn) {
if (this.event[eventName]) {
this.event[eventName].push(eventFn);
} else {
this.event[eventName] = [];
this.event[eventName].push(eventFn);
}
},
emit: function (eventName, eventMag) {
if (this.event[eventName]) {
this.event[eventName].forEach(itemFn => {
itemFn(eventMag);
});
}
}
}
htEvent.on('fileSuccess', function (eventMsg) {
console.log("operation1");
})
htEvent.on('fileSuccess', function (eventMsg) {
console.log("operation2");
})
htEvent.on('fileSuccess', function (eventMsg) {
console.log("operation3");
})
htEvent.emit('fileSuccess', 'hello');
// 结果
operation1
operation2
operation3
上面是events模块的简单使用和通过发布-订阅模式模拟实现events模块,了解更多events模块请查看文档