介绍
发布订阅模式是一种多对一的关系。即订阅者订阅不同的主题,当发布者发布相关的主题的时候呢,订阅者可以收到相关的发布的信息。
实现方式
看代码中的注释,发布订阅就是根据主题来做,并且存进相应的订阅回调。
通俗的说呢,就是list
保存订阅的时候的回调函数,发布的时候传参数进去,被订阅每个回调函数都去执行,那么这个传进去的参数就是我们发布的时候携带的内容啦啦啦。
let events = {
list: {}, //存订阅的回调函数
// 订阅事件
on(key, fn) {
!this.list[key] && (this.list[key] = []);
this.list[key].push(fn);
},
// 发布事件
emit() {
let key = [].shift.call(arguments);
let fns = this.list[key];
if (!fns || fns.length === 0) {
return false;
}
fns.forEach((fn) => {
fn.apply(this, arguments);
});
},
// 取消订阅
remove(key, fn) {
let fns = this.list[key];
if (!fns) return false;
// 如果没有传入对应的函数,将key值对应的缓存函数都清空掉
if (!fn) {
fns && (fns.length = 0);
} else {
fns.forEach((cb, i) => {
cb === fn && fns.splice(i, 1);
});
}
},
// 订阅一次
once(key, fn) {
// 订阅的回调函数
function callback() {
// 先取消前面一次的订阅,再重新订阅
this.remove(key, callback);
fn.apply(this, arguments);
}
// 把主题key包装成callbakc的属性,这样的目的是因为取消订阅的时候取消的是订阅的回调函数,也就是callback。
// 这就是为啥不用this.remove(key,fn)
// 此时传到remove的整个callback函数(包括fn属性的)。因为this.on(key,callback)才调用callback函数(这里会比较难理解)
callback.fn = fn;
this.on(key, callback);
},
};
function cat(data) {
console.log("一起喵喵喵");
console.log(data); // ["xxx","yyy"]
}
function dog() {
console.log("一起汪汪汪");
}
// 就是去订阅pet主题的事件,
events.on("pet", (data) => {
console.log("接受数据");
console.log(data);
});
events.on("pet", cat);
events.on("pet", dog);
// 取消dog的订阅 没有pet主题的话,就把对应的函数全部清空掉(相当于取消了该主题所有的订阅)
events.remove("pet", dog);
// 发布这些事件之后呢,订阅者就可以接受到新发布的东西啦,这些新的东西呢其实就是["xxx","yyy"]
events.emit("pet", ["xxx", "yyy"]);
console.log(events.list);
/*
接受数据
[ 'xxx', 'yyy' ]
一起喵喵喵
{ pet: [ [Function (anonymous)], [Function: cat] ] }
*/
- 创建一个存放订阅者的对象
on
方法用来把回调函数 fn 都加到缓存列表中emit
方法取到arguments
里第一个当做key
,根据key
值去执行对应缓存列表中的函数remove
方法可以根据key
值取消订阅
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZengXPang's blog!
评论