评论

不同页面通过订阅消息事件的方式互相通信

不同页面通过订阅消息事件的方式互相通信

业务背景是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);


最后一次编辑于  02-07  
点赞 1
收藏
评论
登录 后发表内容