PubSub-js语法解析
PubSub-js的语法:
1. token subscribe(msgName, callback): 订阅消息, 并返回一个标识token
2. publish(msgName, data): 异步发布消息
3. publishSync(msgName, data): 同步发布消息
4. unsubscribe(flag): 根据flag取消订阅
例子
//引入pubsub-js库
<script src="https://cdn.bootcss.com/pubsub-js/1.7.0/pubsub.js"></script>
<script>
//订阅消息
PubSub.subscribe('add',function(msg, data){
console.log('消息名:'+msg,'数据:'+data)
})
//订阅消息并获取返回的token
let token = PubSub.subscribe('add',function(msg, data){
console.log('消息名:'+msg,'数据:'+data)
})
//发布消息
PubSub.publish('add','haha') //异步
PubSub.publishSync('add','haha') //同步
console.log('发布消息之后') //打印输出测试
//取消消息订阅
PubSub.unsubscribe(token)
</script>
浏览器输出结果
图解
自定义PubSub-js
模块名称:pub-sub.js
(function (window) {
//定义一个PubSub对象
const PubSub = {}
//分析数据结构 (用来保存所有待处理的回调函数的容器)
/*
{
'消息名1': {
'token1': callback,
'token2': callback
},
'消息名'2: {
'token3': callback,
'token4': callback
},
......
}
*/
//创建容器
let callbackContainer = {}
// 创建一个用于辅助生成token的变量
let id = 0
// 实现功能
//1. token subscribe(msgName, callback): 订阅消息, 并返回一个标识token
PubSub.subscribe = function (msgName, callback) {
// 获取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器还没创建
if (!callbacks) {
// 创建一个小容器,并让callbackContainer[msgName]等于小容器
callbacks = {}
callbackContainer[msgName] = callbacks
}
// 创建一个token
const token = `uid_${++id}`
// 将callback添加到小容器
callbacks[token] = callback
// 把token返回
return token
}
//2. publish(msgName, data): 异步发布消息
PubSub.publish = function (msgName, data) {
setTimeout(() => {
// 获取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器存在
if (callbacks) {
// 将callbackContainer[msgName]里的回调函数全部异步执行,并传递对应的消息名data
Object.values(callbacks).forEach(callback => {
callback(msgName, data)
})
}
})
}
//3. publishSync(msgName, data): 同步发布消息
PubSub.publishSync = function (msgName, data) {
// 获取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器存在
if (callbacks) {
// 将callbackContainer[msgName]里的回调函数全部同步执行,并传递对应的消息名和data
Object.values(callbacks).forEach(callback => callback(msgName, data))
}
}
/*
4. unsubscribe(flag): 根据flag取消订阅
1. flag没有指定: 取消所有
2. flag是一个token值: 取消对应的一个回调
3. flag是msgName: 取消对应的所有
*/
PubSub.unsubscribe = function (flag) {
if (flag === undefined) {
// 如果没传递flag直接将所有消息清除
callbackContainer = {}
} else if (typeof flag === 'string' && flag.indexOf('uid_') === 0) {
// 如果传递的是一个token
Object.values(callbackContainer).forEach(callbacks => {
delete callbacks[flag]
})
} else {
delete callbackContainer[flag]
}
}
window.PubSub = PubSub
})(window)