不同的语言,相同的模式。
最近在关注设计模式的知识,发布订阅模式其实是对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖与它的对象都将得到状态改变的通知。
作用:
1、广泛应用于异步编程中
2、对象间松散耦合的编写代码
自定义事件:
let corp={}; //定义一个公司对象
//这里放一个列表来缓冲回掉函数
crop.list = [];
//去订阅事件
corp.on = function(fn) {
//二话不说 直接把fn先存进列表里
this.list.push(fn)
}
//发布事件
corp.emit = function () {
//当发布的时候再把列表里的函数依次执行
this.list.forEach( cb = {
cb.apply(this , argements)
} )
}
//测试用例
corp.on(function (position , salary) {
console.log( '你的职位时:' + position );
console.log( '期望薪水' + hobby)
} )
corp.emit( '前端' , 10000);
corp.emit( '端茶和倒水' , '足球')
上面通过自定义事件,实现一个简单的订阅发布模式,不过这样实现显然有些粗糙。我们需要分别对应的发布。此处需要一个简单的K值来解决问题。
let corp = {};
//这次换成一个对象类型的缓冲列表
corp.list = {};
corp.on = function(key , fn){
//如果对象中没有对应的K值
//也就是说没有订阅过
//就给K值创建一个缓冲列表
if (!this.list[key]) {
this.list[key] = []
}
//把函数加到对应key的缓冲列表里
this.list[key].push(fn)
}
corp.emit = function() {
//第一个参数是对应的K值
//直接用数组的shift方法去除
let key = [].shift.call(arguments),
fns = this.list[key];
//如果缓冲列表里没有函数就返回false
if (!fns || fns.length === 0) {
return false;
}
//遍历key值对应的缓冲列表
//一次执行函数方法
fns.forEach (fn => {
fn.apply(this , arguments)
})
}
//测试用例
corp.on( 'join' , (position , salary) => {
console.log( '你的职位是:' + position);
console.log( '期望薪水:' + salary)
} )
corp.on( 'other' , (skill , hobby) => {
console.log('你的技能有' + skill)
console.log( '爱好' + hobby)
})
corp.emit( 'join' , '前端' , 10000);
corp.emit( 'join' , '后端' , 10000);
corp.emit( 'other' , '端茶和倒水' ,'足球')
思路:
创建一个对象(缓冲列表)
on方法用来把回掉函数fn,都加到缓冲列表中
emit方法取到arguments里第一个当作key,根据key值去执行对应缓冲列表中的函数
remove方法根据key值去取消订阅
总结:
优点:
对象之间解耦
异步编程中,可以更松耦合的代码编写
缺点:
创建订阅者本身要消耗一定的时间和内存
多个发布者和订阅者嵌套一起的时候,程序很难跟踪维护