在上一篇《Node异步编程的难点》中讲解的异步的问题,但与问题相比,解决方案总是更多。
1. 事件发布/订阅模式events
事件监听模式是一种广泛用于异步编程的模式,是回调函数的事件化,又称为发布/订阅模式。
2.实现events模块
小娅和小萘在商场相中了一件衣服,商场的良心老板events
告知他们,商场近期会搞一个名为“eventName
”的大促销活动,但是时间还未确定,你们只需要订阅我们的公众号on
,发送“eventName
”和你们的联系方式(callback
),活动“eventName
”确定时间后由我们的发布小精灵emit
先生通知你们的。
2.1. on()与emit()方法
于是小萘和路人甲立马就订阅了on活动,留下了“eventName,callback
”
let events = require('events');
var eventEmit = new events();
var callback = (msg)=>{
console.log("小萘先森," + msg);
}
var callback2 = (msg)=>{
console.log("路人甲," + msg);
}
eventEmit.on('eventName',callback);
eventEmit.on('eventName',callback2);
on的作用对指定事件绑定事件处理函数
2.2. once()方法
但是问题来了,小娅最不喜欢订阅和频繁的通知,又不想错过活动,细心的业务员once
看出小娅的犹豫,说到:“没关系!!不订阅on,也能通知,且这次活动后,我们会消除您的信息记录!!”。
于是消除疑虑的小娅按照业务员once
的操作,也行动了起来。
eventEmit.once('eventName', (msg)=>{
console.log("小娅," + msg);
}})
once
绑定的函数,触发emit
只执行一次,这代表执行一次后需要将事件从对应关系中移除掉。- 其实这里的
once
方法将callback
和removeListener
一起包装成了新的处理函数,最终还是走on()
方法。
2.3. newListener()方法
商场老板events
要做一次订阅(on、once
)的统计,希望每次订阅能通知他,他想出了一个叫newListener的方法。
eventEmit.on('newListener',(name,callback){
console.log('客户订阅了'+name);
//这里的callback就是订阅name时的回调函数
});
2.4. removeListener()方法
有订阅就得有取消订阅了,比如上面的路人甲取消订阅;
eventEmit.removeListener('eventName',callback2)
2.5. eventNames()方法
除了大促销活动,还有别的活动可以订阅吗?eventNames
可以查到:
eventEmit.on('大促销', (msg)=>{})
eventEmit.on('大减价', (msg)=>{})
eventEmit.eventNames()// ['大促销', '大减价']
2.6. removeAllListeners()方法
取消所有活动,或者指定的活动。(移除全部或指定 eventName 的监听器。)
eventEmit.on('大促销', (msg)=>{})
eventEmit.on('大减价', (msg)=>{})
eventEmit.on('免费送', (msg)=>{})
eventEmit.removeAllListeners(['大促销'])
eventEmit.eventNames()//['大减价', '免费送'];
eventEmit.removeAllListeners();
eventEmit.eventNames()//[];
2.7 prependListener()方法
emit
将指定的活动对应的处理函数(订阅者回调)依次执行,指定活动的处理函数保存在一个数组里,处理函数先订阅先执行,prependListener
则可以将一个处理函数放在最前面。优先执行。
var callback1 = ()=>{console.log(1)}
var callback2 = ()=>{console.log(2)}
eventEmit.on('大促销', callback1);
eventEmit.on('大促销', callback2);
eventEmit.emit('大促销','msg');
//1
//2
var callback0 = ()=>{console.log(0)}
eventEmit.prependListener('大促销',callback0);
eventEmit.emit('大促销','msg');
//0
//1
//2
2.8 prependOnceListener()
功能和prependListener
差不多,只是prependOnceListener
添加的监听器只执行一次。
//结着上面执行
var callbackOnce = ()=>{console.log('callbackOnce ')}
eventEmit.prependOnceListener('大促销',callbackOnce);
eventEmit.emit('大促销','msg');
//callbackOnce
//1
//2
eventEmit.emit('大促销','msg');
//1
//2
2.9 订阅指定活动的数量listenerCount()
//结着上面执行
eventEmit.listenerCount('大促销');
//2
在on中判断指定事件的处理函数数量,长度等于默认的长度会抛出警告,
getMaxListeners()
能获取到默认长度,返回的是events.defaultMaxListeners
属性。
网友评论