业务背景是tabbar有一个新增的功能,在不同的页面都可以操作新增,保存后首页以及个人中心页面的清单数据都要马上更新,但又不想通过调用接口的方式更新。因此自己搞了一个简单的消息事件订阅,比如A,B,C三个页面同时订阅更新事件,那么在D页面操作了更新动作后就会通知A,B,C三个页面。
代码示例:
event.js
//事件集合
const eventInfo = {};
/**
* 注册消费者
* 相同事件、相同消费者名称时会被覆盖
* @param eventName 事件名称
* @param callback 回调事件
*/
const on = (eventName, callback) => {
const pages = getCurrentPages();
const consumerName = pages[pages.length - 1].route;
if (!eventInfo[eventName]) {
console.warn("广播事件不存在,不处理", eventName, consumerName);
return;
}
const consumerInfo = eventInfo[eventName];
consumerInfo[consumerName] = callback;
console.log("注册消费者完毕=>", eventName, consumerName);
}
/**
* 取消消费者
* @param eventName 事件名称
*/
const off = (eventName) => {
const pages = getCurrentPages();
const consumerName = pages[pages.length - 1].route;
if (!eventInfo[eventName]) {
console.warn("广播事件不存在,不处理=>", eventName, consumerName);
return;
}
const consumerInfo = eventInfo[eventName];
delete consumerInfo[consumerName];
console.log("取消消费者完毕=>", eventName, consumerName);
}
/**
* 推送事件消息
* @param eventName 事件名称
* @param data 消息体
*/
const emit = (eventName, data = {}) => {
if (!eventInfo[eventName]) {
console.warn("广播事件不存在,不处理=>", eventName, data);
return;
}
const consumerInfo = eventInfo[eventName];
const consumerNames = Object.keys(consumerInfo);
consumerNames.forEach(consumerName => {
if (typeof consumerInfo[consumerName] == 'function') {
console.log("推送事件消息完毕=>", eventName, consumerName, data);
consumerInfo[consumerName](data);
} else {
console.warn("消费者没有回调函数,不处理=>", eventName, consumerName, data);
}
})
}
/**
* 批量推送事件消息
* @param eventNames
* @param data
*/
const emitBatch = (eventNames, data) => {
eventNames.forEach(eventName => {
emit(eventName, data);
})
}
/**
* 初始化
*/
const init = () => {
try {
console.log("初始化广播通道");
const eventNames = Object.keys(EVEN_NAME);
eventNames.forEach(eventName => {
eventInfo[eventName] = [];
})
} catch (e) {
console.error("初始化广播通道出现异常:", e)
}
}
/**
* 事件列表
* @type {{REFRESH_CARD_LIST: string, REFRESH_USER_INFO: string}}
*/
const EVEN_NAME = {
RELOAD_CARD_LIST: "RELOAD_CARD_LIST",//重新加载清单数据
RELOAD_USER_INFO: "RELOAD_USER_INFO",//重新加载用户信息
SAVE_CARD_LIST: "SAVE_CARD_LIST",//保存清单
JOIN_INFO_FINISH: "JOIN_INFO_FINISH",//共享完成
JOIN_INFO_FINISH_CONFIRM: "JOIN_INFO_FINISH_CONFIRM",//共享完成确认
}
module.exports = {init, on, off, emit, emitBatch, EVEN_NAME}
订阅消息:
event.on(event.EVEN_NAME.RELOAD_CARD_LIST, data => {
console.log("接收到刷新清单事件推送", data);
this.loadData();
});
event.on(event.EVEN_NAME.RELOAD_USER_INFO, data => {
console.log("接收到刷新用户信息事件推送", data);
auth.setUserInfo2Data(app, this).then();
});
event.on(event.EVEN_NAME.JOIN_INFO_FINISH, data => {
console.log("接收到共享记录完成事件推送", data);
this.loadData();
auth.setUserInfo2Data(app, this).then();
this.toast.showToast({text: "清单共享成功啦"});
})
发送消息:
event.emit(event.EVEN_NAME.SAVE_CARD_LIST, e);