PubSub-js語(yǔ)法解析
PubSub-js的語(yǔ)法:
1. token subscribe(msgName, callback): 訂閱消息, 并返回一個(gè)標(biāo)識(shí)token
2. publish(msgName, data): 異步發(fā)布消息
3. publishSync(msgName, data): 同步發(fā)布消息
4. unsubscribe(flag): 根據(jù)flag取消訂閱
例子
//引入pubsub-js庫(kù)
<script src="https://cdn.bootcss.com/pubsub-js/1.7.0/pubsub.js"></script>
<script>
//訂閱消息
PubSub.subscribe('add',function(msg, data){
console.log('消息名:'+msg,'數(shù)據(jù):'+data)
})
//訂閱消息并獲取返回的token
let token = PubSub.subscribe('add',function(msg, data){
console.log('消息名:'+msg,'數(shù)據(jù):'+data)
})
//發(fā)布消息
PubSub.publish('add','haha') //異步
PubSub.publishSync('add','haha') //同步
console.log('發(fā)布消息之后') //打印輸出測(cè)試
//取消消息訂閱
PubSub.unsubscribe(token)
</script>
瀏覽器輸出結(jié)果

圖解

自定義PubSub-js
模塊名稱:pub-sub.js
(function (window) {
//定義一個(gè)PubSub對(duì)象
const PubSub = {}
//分析數(shù)據(jù)結(jié)構(gòu) (用來(lái)保存所有待處理的回調(diào)函數(shù)的容器)
/*
{
'消息名1': {
'token1': callback,
'token2': callback
},
'消息名'2: {
'token3': callback,
'token4': callback
},
......
}
*/
//創(chuàng)建容器
let callbackContainer = {}
// 創(chuàng)建一個(gè)用于輔助生成token的變量
let id = 0
// 實(shí)現(xiàn)功能
//1. token subscribe(msgName, callback): 訂閱消息, 并返回一個(gè)標(biāo)識(shí)token
PubSub.subscribe = function (msgName, callback) {
// 獲取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器還沒(méi)創(chuàng)建
if (!callbacks) {
// 創(chuàng)建一個(gè)小容器,并讓callbackContainer[msgName]等于小容器
callbacks = {}
callbackContainer[msgName] = callbacks
}
// 創(chuàng)建一個(gè)token
const token = `uid_${++id}`
// 將callback添加到小容器
callbacks[token] = callback
// 把token返回
return token
}
//2. publish(msgName, data): 異步發(fā)布消息
PubSub.publish = function (msgName, data) {
setTimeout(() => {
// 獲取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器存在
if (callbacks) {
// 將callbackContainer[msgName]里的回調(diào)函數(shù)全部異步執(zhí)行,并傳遞對(duì)應(yīng)的消息名data
Object.values(callbacks).forEach(callback => {
callback(msgName, data)
})
}
})
}
//3. publishSync(msgName, data): 同步發(fā)布消息
PubSub.publishSync = function (msgName, data) {
// 獲取存放callback的小容器
let callbacks = callbackContainer[msgName]
// 如果小容器存在
if (callbacks) {
// 將callbackContainer[msgName]里的回調(diào)函數(shù)全部同步執(zhí)行,并傳遞對(duì)應(yīng)的消息名和data
Object.values(callbacks).forEach(callback => callback(msgName, data))
}
}
/*
4. unsubscribe(flag): 根據(jù)flag取消訂閱
1. flag沒(méi)有指定: 取消所有
2. flag是一個(gè)token值: 取消對(duì)應(yīng)的一個(gè)回調(diào)
3. flag是msgName: 取消對(duì)應(yīng)的所有
*/
PubSub.unsubscribe = function (flag) {
if (flag === undefined) {
// 如果沒(méi)傳遞flag直接將所有消息清除
callbackContainer = {}
} else if (typeof flag === 'string' && flag.indexOf('uid_') === 0) {
// 如果傳遞的是一個(gè)token
Object.values(callbackContainer).forEach(callbacks => {
delete callbacks[flag]
})
} else {
delete callbackContainer[flag]
}
}
window.PubSub = PubSub
})(window)