web前端全系列 教程
1839个小节阅读:2244.1k
鸿蒙应用开发
C语言快速入门
JAVA全系列 教程
面向对象的程序设计语言
Python全系列 教程
Python3.x版本,未来主流的版本
人工智能 教程
顺势而为,AI创新未来
大厂算法 教程
算法,程序员自我提升必经之路
C++ 教程
一门通用计算机编程语言
微服务 教程
目前业界流行的框架组合
web前端全系列 教程
通向WEB技术世界的钥匙
大数据全系列 教程
站在云端操控万千数据
AIGC全能工具班
A A
White Night
也叫发布订阅模式,在这种模式中,⼀个订阅者订阅发布者,当⼀个特定的事件发⽣的时候,发布者会通知(调⽤)所有的订阅者。
使⽤观察者模式的好处:
最常⻅的发布订阅模式就是咱们DOM事件,仔细回想⼀下我们要给⼀个按钮,绑定⼀个事件,当我点击按钮的时候我要让他的颜⾊变了,并且⻚⾯弹出⼀个弹出框
我们分析⼀下这个流程
⾸先,我们得知道给哪个按钮的时候绑定事件,然后我们得知道触发事件以后需要⼲什么?
那么在这其中谁是发布者?
是DOM中的按钮,因为是在它身上绑定了事件,当我们点击按钮的时候它便像订阅者发布了这个消息
那么谁是订阅者?
是click事件,当点击按钮时,dom发布了⼀条消息,⽽事件订阅了它,所以当它被点击的时候,订阅者会接收到消息
xxxxxxxxxx
651class Event {
2 constructor() { }
3 // ⾸先定义⼀个事件容器,⽤来装事件数组(因为订阅者可以是多个)
4 handlers = {}
5 // 事件添加⽅法,参数有事件名和事件⽅法
6 addEventListener(type, handler) {
7 // ⾸先判断handlers内有没有type事件容器,没有则创建⼀个新数组容器
8 if (!(type in this.handlers)) {
9 this.handlers[type] = []
10 }
11 // 将事件存⼊
12 this.handlers[type].push(handler)
13 }
14 // 触发事件两个参数(事件名,参数)
15 dispatchEvent(type, params) {
16 // 若没有注册该事件则抛出错误
17 if (!(type in this.handlers)) {
18 return new Error('未注册该事件')
19 }
20 // 便利触发
21 this.handlers[type].forEach(handler => {
22 handler(params)
23 })
24 }
25 // 事件移除参数(事件名,删除的事件,若⽆第⼆个参数则删除该事件的订阅和发布)
26 removeEventListener(type, handler) {
27 // ⽆效事件抛出
28 if (!(type in this.handlers)) {
29 return new Error('⽆效事件')
30 }
31 if (!handler) {
32 // 直接移除事件
33 delete this.handlers[type]
34 } else {
35 const idx = this.handlers[type].findIndex(ele => ele ===
36handler)
37 // 抛出异常事件
38 if (idx === undefined) {
39 return new Error('⽆该绑定事件')
40 }
41 // 移除事件
42 this.handlers[type].splice(idx, 1)
43 if (this.handlers[type].length === 0) {
44 delete this.handlers[type]
45 }
46 }
47 }
48}
49var event = new Event() // 创建event实例
50// 定义⼀个⾃定义事件:"load"
51function load(params) {
52 console.log('load', params)
53}
54event.addEventListener('load', load)
55// 再定义⼀个load事件
56function load2(params) {
57 console.log('load2', params)
58}
59event.addEventListener('load', load2)
60// 触发该事件
61event.dispatchEvent('load', 'load事件触发')
62// 移除load2事件
63event.removeEventListener('load', load2)
64// 移除所有load事件
65event.removeEventListener('load')