优点:对象之间的解耦;异步编程中更松耦合的代码编写
缺点:创建订阅者本身需要消耗一定的时间和内存;多个发布者和订阅者嵌套在一起的时候程序难以跟踪维护。
简单来说就是可以有多个订阅者把自己想要订阅的东西注册到调度中心,然后触发事件,发布者会更新事件到调度中心,订阅者获得自己想要的。简单点说关系如下图:
订阅者A,B,C把自己想要订阅的事件注册到调度中心,包括他的处理过程,发布者F把信息发布到调度中心,调度中心会用订阅者注册的处理过程来处理信息然后返回给各自的订阅者。订阅者和发布者是不直接联系的是要通过调度中心来传递消息,这里和观察者模式还是有区别的。
下面是老师给的一个小练习:
PubSub.js
module.exports = class PubSub {
constructor() {
this.subscribers = {};
}
subscribe(type, fn) {
// todo subscribe,订阅的type不存在那么初始化订阅者[],否则为type添加一个订阅者fn
if(!this.subscribers[type]){
this.subscribers[type] = []
}
this.subscribers[type].push(fn);
}
unsubscribe(type, fn) {
// todo unsubscribe,如果订阅的type不存在直接返回,如果存在就移除所有订阅者
if (!this.subscribers[type]) return;
this.subscribers[type] = [];
}
publish(type, ...args) {
// todo publish
if(this.subscribers[type]){
for(let i=0, len = this.subscribers[type].length; i <len; i++){
this.subscribers[type][i](...args)
}
}
}
test.js
describe('PubSub', () => {
let ob = new PubSub();
it('subscribe -> publish', async () => {
let sum = 0;
let val = Math.random() * 1e9 >> 0;
ob.subscribe('add', (val) => sum += val);
ob.publish('add', val);
assert.ok(sum === val);
});
it('subscribe -> publish -> unsubscribe -> publish', async () => {
let sum = 0;
let val = Math.random() * 1e9 >> 0;
let add = (val) => sum += val;
ob.subscribe('add', add);
ob.publish('add', val);
assert.ok(sum === val);
sum = 0;
val = Math.random() * 1e9 >> 0;
ob.unsubscribe('add', add);
ob.publish('add', val);
assert.ok(sum !== val);
});
});