发布订阅模式
我们假定,存在一个事件中心,某个任务执行完成,就像事件中心发布一个信号,其他任务可以向信号中心订阅这个信号,从而知道什么时候自己可以开始执行,这就叫做发布订阅模式;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/*
* * 发布订阅模式
*
* * 订阅者
* * 发布者
* * 事件中心
*/
class EventEmitter {
constructor () {
this.subs = Object.create(null)
}
// 订阅者
$on (eventType, handler) {
this.subs[eventType] = this.subs[eventType] || []
this.subs[eventType].push(handler)
}
// 发布者
$emit (eventType) {
if (this.subs[eventType]) {
this.subs[eventType].forEach(handler => {
handler()
})
}
}
}
// 测试
let em = new EventEmitter()
em.$on('click', () => {
console.log('click1')
})
em.$on('click', () => {
console.log('click2')
})
em.$emit('click')
</script>
</body>
</html>
观察者模式
观察者模式定义了对象间的一种一对多的组合关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。观察者模式必须包含两个角色:观察者和观察对象,两者之间存在“观察”的逻辑关联,当观察对象状态发生改变时,将通知相应的观察者以更新状态,这就是观察者模式;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/*
* * 观察者模式
*
* * 观察者(订阅者)-- Watcher
* * * update(): 当事件发生时,具体要做的事情
*
* * 目标(发布者)--Dep
* * * subs 数组: 存储所有的观察者
* * * addSub(): 添加观察者
* * * notify(): 当事情发生,调用所有观察者的update()方法
*
* * 没有事件中心
*/
class Dep {
// (目标)发布者
constructor () {
this.subs = []
}
// 添加观察者
addSub (sub) {
if (sub && sub.update) {
this.sub.push(sub)
}
}
// 通知所有观察者
notify () {
this.subs.forEach(sub => {
sub.update()
})
}
}
class Watcher {
update () {
console.log('update')
}
}
// 测试
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
</script>
</body>
</html>