/** 发布者 */
class Publish {
name: string
id: number
messageMap: { [key: string]: {id: number; name: string; [x: string]: any}[] }
/** name等同于给当前发布者一个名称 */
constructor(name: string) {
/** 消息事件订阅者集合对象 */
this.messageMap = {}
/** 随机id模拟唯一 */
this.id = Date.now() + Math.ceil(Math.random() * 10000)
this.name = name
}
/** 添加消息订阅者(subscriber等于订阅者) */
addListener(subscriber: any, message: string) {
if (!subscriber || !message) return false
/** 如果消息列表不存在,就新建 */
if (!this.messageMap[message]) {
this.messageMap[message] = []
}
/** 比对ID查询!!! */
const existIndex = this.messageMap[message].findIndex(exitSubscriber => exitSubscriber.id === subscriber.id)
/** 不存在这个订阅者时添加 */
if (existIndex === -1) {
/** 吧订阅者装进去 */
this.messageMap[message].push(subscriber)
} else {
/** 存在的时候呢 直接替换 */
this.messageMap[message][existIndex] = subscriber
}
}
/** 删除消息订阅者 */
removeListener(subscriber: any, message: string) {
if (!subscriber) return false
/** 如果传了message只删除此message下的订阅关系,否则删除此订阅者的所有订阅关系 */
const messages = message ? [message] : Object.keys(this.messageMap)
/** 遍历Key */
messages.forEach(_message => {
const subscribers = this.messageMap[_message]
if (!subscribers) return false
let i = subscribers.length
while (i--) {
if (subscribers[i].id === subscriber.id) {
subscribers.splice(i, 1)
}
}
/** 数组元素如果没有了。直接吧订阅器删除 */
if (!subscribers.length) delete this.messageMap[_message]
})
}
/** 发布通知 */
publish<D extends any>(message: string, info: D) {
const subscribers = this.messageMap[message] || []
let handlerKey = message + "_" + this.id + "_handler"
/** 找出当前索引订阅者,依次发送通知 */
subscribers.forEach(subscriber => {
subscriber[handlerKey](subscriber, info)
})
return this
}
}
export default Publish
type listenType = {
publisher: any,
message: string,
handler: (subscribe: {[x: string]: any}, info: any) => void
}
/** 订阅者 */
class Subscribe {
id: number;
name: string;
[x: string]: any
/** name等同于给当前订阅者一个名称 */
constructor(name: string = 'subscriber') {
this.name = name
/** 随机id模拟唯一 */
this.id = Date.now() + Math.ceil(Math.random() * 10000)
}
/**
* 订阅器
* @publisher 订阅的是哪个发布者(比如你订阅的是xxx)
* @message 订阅的消息,(非常重要的字段)(比如你订阅的是xx发的招工信息key。绑定关系)
* @handler 收到消息后的处理方法
*/
listen({publisher, message, handler}: listenType) {
/** 订阅消息的回调函数 */
if (publisher) {
/** 一个订阅者可以同时订阅多个发布者,所以回调函数要拼接上对应发布者的id */
this[message + '_' + publisher.id + "_handler"] = handler
publisher.addListener(this, message)
}
/** 链式 */
return this
}
/** 取消订阅 */
unlisten(publisher: any, message: string) {
if (publisher) {
publisher.removeListener(this, message)
}
/** 链式 */
return this
}
}
export default Subscribe
import {Subscribe, Publish} from "."
/** 示例 (可以链式,多绑定)说白了就是一个人可以绑定A的发布者,也可以绑定B的发布者,还可以绑定A的发布其他信息
* LoginSubscribe.listen({
publisher: APublish, // 绑定发布者是A
message: '找活', // 绑定发布者是发布的找活
handler: (self, info) => {
console.log(self, dispatch)
}
}).listen({
publisher: BPublish,
message: '招工',
handler: (self, info) => {
consol.log(info == '我要找一个工人啦')
console.log(self, dispatch)
}
})
BPublish.publish('招工', '我要找一个工人啦!')
如不多个人绑定了B的招工,那么B发布者一旦放送信息,全体订阅者会收到信息
*/
/** 登录的发布者 */
const LoginPublish = new Publish('LoginPublish')
/** 登录的订阅者 */
const LoginSubscribe = new Subscribe('LoginSubscribe')
/** 你可以在这里处理更多的发布订阅 */
// ....
export {
LoginPublish,
LoginSubscribe
}