什么是发布订阅模式?
从字面意思来讲,分为发布和订阅两个过程。
- 发布:就是事件发生的过程,比如发布了一个新闻,发布了一篇文章。
- 订阅:就是接受到发布的事件之后做的事情,比如你订阅了我的微信公众号,我发布一篇文章,你接受到了,然后打开了,点了个赞(做的事情)。
实际上,我们平常使用中,是先订阅,再发布这样的过程,如果没有订阅,发布有啥意义嘛。。
有啥用?
我个人理解就是解耦,将发布和订阅这两个过程分离开。
放“码”过来
function Event () {
this.evnets = {};
}
Event.prototype.on = function (eventName, callback) {
this.evnets[eventName] = callback;
}
Event.prototype.emit = function (eventName, args) {
this.evnets[eventName].handler(args);
}
打完收工。
优化一下,增加off和once方法。
function Event () {
this.evnets = {};
}
Event.prototype.on = function (eventName, callback) {
this.evnets[eventName] = {
once: false,
handler: callback
};
}
Event.prototype.emit = function (eventName, args) {
this.evnets[eventName].handler(args);
if (this.evnets[eventName].once) { // 如果是once,则执行完成之后off掉
this.off(eventName)
}
}
Event.prototype.off = function (eventName) {
delete this.evnets[eventName];
}
Event.prototype.once = function (eventName, callback) {
this.evnets[eventName] = {
once: true,
handler: callback
};
}
再优化?!
有时候,我们会把一个事件绑定多次的情况。
event.on('click', function (args) {
console.log('第一次click')
console.log(args);
});
event.on('click', function (args) {
console.log('第二次click')
console.log(args);
});
这种情况,我们希望两次绑定的事件都触发咯,但是上面的写法,第二次会覆盖第一次。这种情况处理也很简单,this.events[eventName]使用数组处理就好了,but!!!那样的话,我们的off方法就要修改,思路就是绑定的时候,要手动传入一个id。。。。
算了,这种实现简直就是反人类,如果有这种场景,那么用两个不同的eventName吧!
哪里有用到?
实际中,比如之前的jQuery有一个trigger方法、Vue的响应式设计、我们使用的promise等,底层还是借鉴了发布订阅模式的思想。
最后
第一次发文,求轻拍。。。