fly coding 前端实现功能通信功能,使用Storage加订阅模式监听方式

近来,想实现前端功能之间的通信功能。众所周知,前端跨页面之间通信的方式有很多种。

譬如:localStorage、BroadCast channel、cookie、postMessage等多种。

在浏览器兼容,使用复杂度各方面综合考虑下,我准备采用localStorage监听方案,从而实现功能之间跨页面通信的问题。

一、封装跨页面通信工具

1、需求分析,思路梳理

由于,采用localStorage监听方案。故而,我准备封装一个工具函数,实现操作storage内部值的函数。

对于此工具的封装,我暂时有以下几点要求:

1、可以直接查到所有的存储数据,方便后期对此类数据做处理。基于此要求,我的想法是给所有缓存的key,添加固定的前缀,后期获取值时,可过滤指定的键,即可实现。

2、可以区分通知类型,传递数据。基于此要求,我的想法是缓存值对象,将定义为以下对象,当数据发生变化时,可通过对应属性判断各种类型和取值。

3、由于是对功能进行监听,也存在同一个页面多个功能的情况,故而需要实现同页面的监听回调。但是,有些浏览器对同页面监听是不支持的。所以,我考虑采用“订阅”模式,来做到同页面之间的“发布、订阅”功能。

{
  "type": "通知类型",
  "data": "通知数据",
  "time": "当前时间戳"
}

此次设计,我暂时想到的就是以上两点要求,等后期如有添加别的要求,再战。

2、代码实现

  • Storage通信模式
/**




* 跨页面通信工具类
*
* @type {{}}
*/
const PageNotifyUtil = {


  // 页面通信主键
  PAGE_NOTIFY_KEY : "PAGE_NOTIFY_KEY_1689B68216BB4B3CA3CF2BEA19A8C33B_",

  /**
  * 获取页面Key
  *
  * @param pageKey
  * @returns {string}
  */
  getNotifyKey(notifyKey) {
    return PageNotifyUtil.PAGE_NOTIFY_KEY + notifyKey;
  },

  /**
  * 通知页面
  *
  * @param pageKey
  * @param type
  * @param data
  */
  notify(notifyKey, type, data) {
    let cacheValue = {
      "type": type,
      "data": data,
      "time": engineCommon.getTimeStamp()
    };
    StorageUtil.setValue(this.getNotifyKey(notifyKey), JSON.stringify(cacheValue));
  },

}
  • 发布订阅模式事件处理中心
/**




 * 发布订阅事件
 *


 * @type {{emitFunc(*=, *=, *=): void, emit(*, ...[*]=): void, events: {}, off(*, *): void, on(*, *=): void}}
 */

const EventEmitter =  {


    // 事件缓存对象
    events: {},
    /**
     * 订阅
     *
     * @param eventName
     * @param callback
     */
    on(eventName, callback) {
        (this.events[eventName] || (this.events[eventName] = [])).push(callback);
    },
    /**
     * 取消订阅
     *
     * @param eventName
     * @param callback
     */
    off(eventName, callback) {
        const eventList = this.events[eventName];
        eventList && eventList.length && (this.events[eventName] = eventList.filter((f) => f !== callback));
    },
    /**
     * 通知
     *
     * @param eventName
     * @param arg
     */
    emit(eventName, ...args) {
        this.events[eventName] && this.events[eventName].forEach(fn => fn.apply(this, args));
    },
    /**
     * 通知功能
     *
     * @param eventName
     * @param type
     * @param data
     */
    emitFunc(eventName, type, data) {
        // Storage 通知
        PageNotifyUtil.notify(eventName, type, data);
        // 同页面事件通知
        EventEmitter.emit(eventName, type, data);
    }
}

二、功能引擎类实现监听

1、需求分析,思路梳理

如标题所示,我本篇重点在于实现“功能”之间的通信。故而,我将实现的不是单、多页面之间的通信。我的重点在于实现“功能”通信。

我此前所设计的功能架构,大致由下图所示:

如上图所示,我需要在基础引擎类中实现监听,并且提供回调函数,子功能具体实现回调,即可成功回调值对应的子功能中。

2、代码实现

  • 通知键获取
/**




 * 获取通知键
 *


 * @returns {string}
 */

engine.getNotifyKey = function () {
  // 拼接规则  功能编码 +  功能类型 + 功能模块编码
  let notifyKey = engine.funcCode + "_" + engine.getFuncType();
  if (engineCommon.isNotEmpty(engine.configCode)) {
    notifyKey += "_" + engine.configCode;
  }
  return notifyKey;
}

  • 功能通知监听
// 监听功能
window.onstorage = function (e) {
  // 判断是否为当前功能
  if (e.key.indexOf(engine.getNotifyKey()) != -1) {
    let data = JSON.parse(e.newValue);
    engine.notifyCallBack(data.type, data.data)
  }
};
// 同页面事件监听
EventEmitter.on(engine.getNotifyKey(), engine.notifyCallBack);
  • 通知回调函数
/**




 * 通知回调函数
 *


 * @param type
 * @param data
 */
engine.notifyCallBack = function (type, data) {
  console.log(` 收到通知回调:${engine.getNotifyKey()} --> ${type} --> ${data}.`);
  // 通知回调函数调用
  if (engine.onNotifyCallBack) {
    engine.onNotifyCallBack(type, data);
  }
}

  • 功能销毁回调
/**




 * 引擎销毁回调
 */
engine.destroy = function () {
  // 删除事件监听
  EventEmitter.off(engine.getNotifyKey(), engine.notifyCallBack);
}

三、实现效果测试

1、测试代码编写

由于是测试代码,我的想法是统一写在事件处理调用函数中,这样的话所有的事件绑定都有通知效果。我这边考虑对角色管理功能进行通知测试,它的编码为“Sy_Role_100201_DRIVEN_MANAGE_MODEL”。

接下来,我将实现测试功能:

EventEmitter.emit("Sy_Role_100201_DRIVEN_MANAGE_MODEL", "test", "我是测试通知数据");

2、功能实现效果

前端通信功能-实现效果.gif

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYqXJWng' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片