1.发布订阅模式与观察者模式的代码实现
发布订阅模式:
class PubSub {
constructor() {
this.events = {}
}
subscribe(event, callback) {
// 订阅事件
if (this.events[event]) {
this.events[event].push(callback)
} else {
this.events[event] = [callback]
}
}
publish(event, ...args) {
// 发布消息,触发对应的回调
const subscribeEvents = this.events[event]
if (subscribeEvents && subscribeEvents.length) {
subscribeEvents.forEach(callback => {
callback.call(this, ...args)
})
}
}
unsubscribe(event, callback) {
// 删除某个订阅,保留其他订阅
const subscribeEvents = this.events[event]
if (subscribeEvents && subscribeEvents.length) {
this.events[event] = this.events[event].filter(cb => cb !== callback)
}
}
}
使用:(可以解决回调地狱)
const request = require("request");
const pubSub = new PubSub();
request('https://www.baidu.com', function (error, response) {
if (!error && response.statusCode == 200) {
console.log('get times 1');
// 发布请求1成功消息
pubSub.publish('request1Success');
}
});
// 订阅请求1成功的消息,然后发起请求2
pubSub.subscribe('request1Success', () => {
request('https://www.baidu.com', function (error, response) {
if (!error && response.statusCode == 200) {
console.log('get times 2');
// 发布请求2成功消息
pubSub.publish('request2Success');
}
});
})
// 订阅请求2成功的消息,然后发起请求3
pubSub.subscribe('request2Success', () => {
request('https://www.baidu.com', function (error, response) {
if (!error && response.statusCode == 200) {
console.log('get times 3');
// 发布请求3成功消息
pubSub.publish('request3Success');
}
});
})
观察者模式:
class Observe {
constructor() {
this.state = ''
this.observes = []
}
getState() {
return this.state
}
setState(state) {
this.state = state
this.notify()
}
addObserve(observe) {
this.observes.push(observe)
}
notify() {
this.observes.forEach(observe => observe.update())
}
}
class Watcher {
constructor(name, sub) {
this.name = ''
this.sub = sub
this.sub.addObserve(this)
}
update() {
console.log(this.sub.getState())
}
}
var sub = new Observe()
var a = new Watcher('a', sub)
var b = new Watcher('b', sub)
sub.setState('3') //3,3
观察者模式与发布订阅模式的区别在于:
- 观察者模式是一个主题对应多个观察者,主题更新了,会告诉所有的观察者
- 发布订阅模式是,多个事件(主题),一个事件对应多个观察者。发布订阅模式中,可以自己定义事件的名称,去更新订阅了对应事件的观察者,而观察者模式就只有一个主题,不能够自定义事件名称。
DOM自定义事件:
原理应该是通过事件冒泡机制进行传递的。
//创建一个event对象
let event = document.createEvent("HTMLEvents");
//自定义事件名 是否冒泡 是否阻止默认事件
event.initEvent("autoEventName",true,false)
//监听事件
document.addEventListener("autoEventName",(e)=>{
console.log(e)
})
//派发这个事件
document.dispatchEvent(event)