forked from opentiny/tiny-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseMessage.js
More file actions
138 lines (123 loc) · 3.82 KB
/
Copy pathuseMessage.js
File metadata and controls
138 lines (123 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
let lastMessage = null
const subscribers = { '': {} }
/**
* 订阅消息。
*
* const { subscribe } = useMessage()
* subscribe({ topic: 'myTopic', callback: data => console.log(data) })
*
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, subscriber(可选): 消息集合, callback: 接收到消息之后的回调用函数 }
* @return {Object} { topic: 消息名称, subscriber: 消息集合 }
*/
const subscribe = ({ topic, subscriber, callback } = {}) => {
const root = subscribers['']
let listeners = root
if (topic && typeof topic === 'string' && typeof callback === 'function') {
if (subscriber && typeof subscriber === 'string') {
listeners = subscribers[subscriber] || {}
subscribers[subscriber] = listeners
}
const callbacks = listeners[topic] || []
listeners[topic] = callbacks
callbacks.push(callback)
const lastEvent = callbacks.lastEvent || (root[topic] && root[topic].lastEvent)
if (lastEvent) {
callback(lastEvent.data)
}
}
return { topic, subscriber }
}
/**
* 取消订阅。
*
* //订阅消息
* const { subscribe } = useMessage()
* let message = subscribe({ topic: 'myTopic', callback: data => console.log(data) })
*
* //取消订阅
* const { unsubscribe } = useMessage()
* unsubscribe({topic: 'myTopic'}) // 方式一
* unsubscribe(message) // 方式二
*
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, subscriber(可选): 消息集合 }
*/
const unsubscribe = ({ topic, subscriber } = {}) => {
if (topic && typeof topic === 'string') {
const removeListener = (subscriber) => {
const listeners = subscribers[subscriber]
if (listeners) {
delete listeners[topic]
if (subscriber && !Object.getOwnPropertyNames(listeners).length) {
delete subscribers[subscriber]
}
}
}
if (subscriber && typeof subscriber === 'string') {
removeListener(subscriber)
} else {
Object.keys(subscribers).forEach((key) => {
removeListener(key)
})
}
}
}
/**
* 发布消息。
* const { publish } = useMessage()
* publish({ topic: 'myTopic', data: 'string' })
* publish({ topic: 'myTopic', data: {} })
*
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, data(string | object): 消息内容 }
*/
const publish = ({ topic, data } = {}) => {
if (topic && typeof topic === 'string') {
Object.values(subscribers).forEach((value) => {
let callbacks = value[topic] || []
if (callbacks.length) {
callbacks.forEach((callback) => callback(data))
} else {
value[topic] = callbacks
}
callbacks.lastEvent = { data }
})
}
}
/**
* 广播消息。
* const { broadcast } = useMessage()
* broadcast({ topic: 'myTopic', data: 'string' })
* broadcast({ topic: 'myTopic', data: {} })
*
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, data(string | object): 消息内容 }
*/
const broadcast = ({ topic, data }) => {
if (topic && typeof topic === 'string') {
lastMessage = { topic, data }
publish(lastMessage)
}
}
export default () => {
// 新use的message自动广播上次的异步消息
lastMessage && publish(lastMessage)
return {
subscribe,
unsubscribe,
publish,
broadcast
}
}