代码实现
// event.js
var Event = (function() {
var _callbacks = {}, listen, emit, remove; //_callbacks 缓存所有订阅者的回调函数
listen = function(eventName, fn) {
if(!_callbacks[eventName]) {
_callbacks[eventName] =[fn];
} else{
_callbacks[eventName].push(fn);
}
};
//写法一,要求传入两个参数
// emit = function(eventName,argus) {
// var fns = _callbacks[eventName]
// if(!fns || fns.length === 0) {
// return false;
// }
// var args = {
// eventName: eventName,
// argus: argus,
// eventDate: new Date() //可以添加每次事件触发时间
// }
// for(let i=0;i<fns.length;i++){
// fns[i].call(this,args)
// }
// }
//写法二,可以追加随意数量参数
emit = function() {
var eventName = Array.prototype.shift.call(arguments),fns = _callbacks[eventName];
if(!fns || fns.length === 0) {
return false;
}
for(let i=0;i<fns.length;i++){
fns[i].apply(this,arguments)
}
};
remove = function(eventName, fn){
var fns = _callbacks[eventName];
if(fns.length!==0) {
for(let i=fns.length-1;i>=0;i--){
var _fn = fns[i];
if(_fn === fn) {
fns.splice(i,1);
}
}
}
};
return {
listen: listen,
emit:emit,
remove:remove
}
})();
/** index.jsx */
<body>
<button id='count'>点击</button>
<div id='showCount'></div>
<script src='./event.js'></script>
<script>
//发布
var a=(function(){
var count =0;
var button = document.getElementById('count');
button.onclick=function(){
Event.emit('add', count++)
}
})();
//订阅
var b=(function(){
var div=document.getElementById('showCount');
Event.listen('add',function(count){
div.innerHTML = count;
})
})()
</script>
</body>
含义说明
又称观察者模式,一对多关系,发布者状态改变时,所有相关事件订阅者收到通知,触发相应回调。
应用
1.组件间传递数据、框架间跨组件传递数据。
2.异步编程中,替代回调函数,可以订阅ajax之后的事件,只要订阅自己需要的部分。
3.对象之间的松耦合。同一发布者的内部代码改变,只要约定的事件名称没有改变,不影响订阅;新增订阅者不影响其他订阅者。
不足
1.但使用过度,代码不好理解和维护。
2.无法知道消息传送是成功的还是失败的,信道不会通知系统消息传送的状态。
介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景
观察者模式中主体和观察者是互相感知的,发布-订阅模式是借助第三方来实现调度的,发布者和订阅者之间互不感知
发布-订阅模式就好像报社, 邮局和个人的关系,报纸的订阅和分发是由邮局来完成的。报社只负责将报纸发送给邮局。
观察者模式就好像 个体奶农和个人的关系。奶农负责统计有多少人订了产品,所以个人都会有一个相同拿牛奶的方法。奶农有新奶了就负责调用这个方法。
https://juejin.cn/post/6844903513009422343
引申
当多处同时出发事件,作用于同一作用域,应该怎么控制程序不出错?
我的两个思路:
1.设定开关变量(flag)监测是否正在执行某操作,等开关打开,其他事件才可执行;
2.队列(queue)形式,维护回调函数,批量处理