一、什么是发布者-订阅者模式
订阅者把自己想订阅的事件注册到调度中心,当发布者发布该事件到调度中心,就是该事件触发时,由调度中心统一调度订阅者注册到调度中心的处理代码。
基本思想就是内部保存了一个对象存储订阅的函数,调用者通过名字来触发函数,订阅多个就按照队列的形式触发。
二、发布者-订阅者模式实现
//发布订阅模式
class EventEmitter {
constructor() {
//事件对象,用来存放订阅的名字和事件
this.events = {};
}
//存放订阅事件的方法
on(eventName, callback) {
if (!this.events[eventName]) {
//一个名字可以订阅多个事件,所以使用数组
this.events[eventName] = [callback]
} else {
//存在则push到数组的尾部
this.events[eventName].push(callback)
}
}
//触发事件的方法
emit(eventName) {
//遍历执行所有订阅的事件
this.events[eventName] && this.events[eventName].forEach(cb => cb())
}
//移除订阅事件的方法
removeListener(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName] = this.events[eventName].filter(cb => cb != callback)
}
}
//只执行一次订阅的事件,执行完就移除
once(eventName, callback) {
let fn = () => {
callback();
//执行一次之后就移除
this.removeListener(eventName, fn)
}
//存放到事件对象中
this.on(eventName, fn);
}
}
//测试实例
let em = new EventEmitter();
let workday = 0;
em.on("work", function() {
workday++;
console.log("work everyday");
})
em.once("love", function() {
console.log("just love you");
})
function makeMoney() {
console.log("make one million money");
}
em.on("money", makeMoney)
let time = setInterval(() => {
em.emit("work");
em.removeListener("money", makeMoney)
em.emit("money")
em.emit("love")
if (workday == 5) {
console.log("have a rest");
clearInterval(time)
}
}, 1);
原文转载自:https://blog.youkuaiyun.com/qq_45701130/article/details/124301190