const eventEmitter = {
list: [], // {1}
on: function( key, fn ){ // {2}
if ( !this.list[ key ] ){
this.list[ key ] = [];
}
this.list[ key ].push( fn ); // 订阅的消息添加进缓存列表
},
emit: function(){ // {3}
const key = Array.prototype.shift.call( arguments ), // 获取传入的第一个参数
fns = this.list[ key ]; // 通过key获取到相应的事件集合
if ( !fns || fns.length === 0 ){
return false;
}
for( let i = 0; i<fns.length; i++ ){
fns[i].apply( this, arguments ); // 调用相应订阅函数
}
},
remove : function( key, fn ){ // {4}
const fns = this.list[ key ];
if ( !fns ){ // 如果key对应的消息没有被人订阅,则直接返回
return false;
}
if ( !fn ){ // 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅
fns && ( fns.length = 0 );
}else{
for ( let l = fns.length - 1; l >=0; l-- ){ // 反向遍历订阅的回调函数列表
let _fn = fns[ l ];
if ( _fn === fn ){
fns.splice( l, 1 ); // 删除订阅者的回调函数
}
}
}
}
};
代码解释:
- {1} list 数组用来存储订阅数据
- {2} on 用来订阅事件
- {3} emit 用来发布事件
- {4} remove 删除相关订阅
function user1 (content) { console.log('用户1订阅了:', content); }
function user2 (content) { console.log('用户2订阅了:', content); }
eventEmitter.on("订阅事件A",user1); eventEmitter.on("订阅事件A",user2);
eventEmitter.emit("订阅事件A","哈哈");
发布—订阅模式的优点非常明显,一为时间上的解耦,二为对象之间的解耦。它的应用非常广泛,既可以用在异步编程中,也可以帮助我们完成更松耦合的代码编写。 从架构上来看,无论是MVC还是MVVM(vue.js),都少不了发布—订阅模式的参与,而且JavaScript本身也是一门基于事件驱动的语言。
作者:小小LION 链接:https://juejin.im/post/5ecf04ace51d45786d3fda70 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Comments