Appearance
自定义事件
如何一步步实现发布—订阅模式。
首先要指定好谁充当发布者(比如售楼处);
然后给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者(售楼处的花名册);
最后发布消息的时候,发布者会遍历这个缓存列表,依次触发里面存放的订阅者回调函 数(遍历花名册,挨个发短信)。
另外,我们还可以往回调函数里填入一些参数,订阅者可以接收这些参数。这是很有必要的, 比如售楼处可以在发给订阅者的短信里加上房子的单价、面积、容积率等信息,订阅者接收到这 些信息之后可以进行各自的处理:
javascript
const salesOffices = {}
salesOffices.clientList = []
// 增加订阅者
salesOffices.listen = function (fn) {
this.clientList.push(fn)
}
// 发布消息
salesOffices.trigger = function (...args) {
const { clientList } = this
for (let i = 0, l = clientList.length; i < l; i++) {
clientList[i].apply(this, args)
}
}
// A 订阅消息
salesOffices.listen(function (price, squareMeter) {
console.log(price, squareMeter)
})
// B 订阅消息
salesOffices.listen(function (price, squareMeter) {
console.log(price, squareMeter)
})
// 发布消息
salesOffices.trigger(2000000, 88)
salesOffices.trigger(3000000, 110)至此,我们已经实现了一个最简单的发布—订阅模式,但这里还存在一些问题。我们看到订 阅者接收到了发布者发布的每个消息,虽然 A 只想买 88 平方米的房子,但是发布者把 110 平 方米的信息也推送给了 A,这对 A 来说是不必要的困扰。所以我们有必要增加一个标示 key, 让订阅者只订阅自己感兴趣的消息。改写后的代码如下:
javascript
const salesOffices = {}
salesOffices.clientList = {}
// 增加订阅者
salesOffices.listen = function (key, fn) {
(this.clientList[key] || (this.clientList[key] = [])).push(fn)
}
// 发布消息
salesOffices.trigger = function (key, ...args) {
const fns = this.clientList[key]
if (!fns || fns.length === 0) {
return
}
for (let i = 0, l = fns.length; i < l; i++) {
fns[i].apply(this, args)
}
}
// A 订阅消息
salesOffices.listen('squareMeter88', function (price, squareMeter) {
console.log(price, squareMeter)
})
// B 订阅消息
salesOffices.listen('squareMeter110', function (price, squareMeter) {
console.log(price, squareMeter)
})
// 发布消息
salesOffices.trigger('squareMeter88', 2000000, 88)
salesOffices.trigger('squareMeter110', 3000000, 110)很明显,现在订阅者可以只订阅自己感兴趣的事件了。