node-EventEmitter(一)

190 阅读2分钟

node.js里面所有的异步I/O操作再完成时都会发送一个事件到事件队列。

node 里events模块里只包含了一个对象:EventEmitter。EventEmitter的核心就是对事件触发以及事件的监听的封装。

EventEmitter本质上是一个观察者模式的实现。是不是很熟悉?我们之前实现的vue的数据响应化也是观察者模式,道理上是相同的。

const EventEmitter = require('events').EventEmitter; 
const event = new EventEmitter(); 
event.on('some_event', ()=> { 
    console.log('some_event 事件触发'); 
}); 
setTimeout(()=> { 
    event.emit('some_event'); 
}, 1000);

当然,实例的emit是可以传参的:

event.emit('some_event' , num ); 

监听的时候

event.on('some_event',num=>{
    console.log(num);
})

既然是观察者模式,也可以监听多个事件:

event.on('some_event',num=>{
    console.log(num);
})
event.on('some_event',num=>{
    console.log(num++);
})

上面就是EventEmitter的简单应用。下面我们实现一个简单的EventEmitter。

on(event, listener) : 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。

emit(event, ...argus) : 按监听器的顺序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

class EventEmitter {
    constructor() {
        this.handler = {}
    }
    on(eventname, callback) {
        if (!this.handler[eventname]) {
            this.handler[eventname] = [];
        }
        this.handler[eventname].push(callback);
    }
    emit(eventName, ...arg) {
        if (this.handler[eventName]) {
            this.handler[eventName].map(item => item(...arg))
        }
    }
}

我们可以测试一下

let event = new EventEmitter();
event.on('count', num => {
    console.log("The count now is " + num);
});
event.on('count', num => {
    console.log("Also you can handle it " + num*100);
});
let num = 0;
setInterval(() => {
    event.emit('count', num++);
}, 1000)

结果:

这样一个简单的EventEmitter我们就实现了。

另外我还有一点感触比较深的就是看了一篇文章,是讲函数式编程的,感觉对我的启发还挺大,上面说应该尽量减少for循环这一类的语句,取而代之的是函数的方法,确实,这样写代码的优雅度明显就提高了。而且联想到React推出来的Hooks以及memo等高阶函数,感觉确实有这个趋势,是向函数编程靠拢。随口一说,仅当作自己的学习心得。