中介者封装

一、中介者简介

功能:订阅、发布、取消订阅、取消发布

基本使用方式

  • 订阅:$intermediary.subscribe(“header”,“username”,function (username) {});
  • 发布:$intermediary.publish(“header”,“username”,“hang”);
  • 取消订阅:$intermediary.cancelSubscribe(“header”,“username”,fn);
  • 取消发布:$intermediary.cancelPublish(“header”,“username”,“hang”);

整体架构

  • 订阅信息 > 命名空间 > 信息名 > 回调函数
  • 发布信息 > 命名空间 > 信息名 > 内容
  • 都是一对多的关系

注意点

  • 订阅只能接收指定 命名空间 和 信息名 发布的信息
  • 订阅可以在发布前,也可在发布后,如果在发布后订阅的,默认无法接收到之前的内容,如果想接收,需要在形参最后加上一个 true
    例如:$intermediary.subscribe(“header”,“username”,function (username) {},true);
  • 取消订阅 和 取消发布 可以传任意的参数,将会删除任意的节点
    例如:$intermediary.cancelSubscribe(“header”);
    将会删除订阅信息中 “header” 的命名空间,同样,传两个参数,则会删除指定的信息名
  • 如果删除的不存在 或 没有传参,则会返回 false ,默认返回 true
  • 回调函数 和 内容 都可重复
  • 回调函数 和 内容 都会一直保存,不需要时,及时删除

二、实现代码

const $intermediary = (function () {
    /*订阅队列*/
    const subscriptionQueue = {};
    /*发布队列*/
    const publishQueue = {};
    /*创建命名空间,不同的模块使用不同的命名空间,方便维护*/
    const createNameSpace = function (nameSpace,queue) {
        queue[nameSpace] = queue[nameSpace] || {};
    }
    /*创建信息名,在指定队列和命名空间下创建信息名*/
    const createMsgName = function (msgName,nameSpace,queue) {
        createNameSpace(nameSpace,queue);
        queue[nameSpace][msgName] = queue[nameSpace][msgName] || [];
    }
    /*删除属性名,除了回调函数和内容用数组保存,其他都为对象,调用此方法删除*/
    const deletePropertyName = function (obj,propertyName) {
        let hasPropertyName = false;
        for (let index in obj) {
            if (index === propertyName) {
                hasPropertyName = true;
                delete obj[propertyName];
            }
        }
        return hasPropertyName;
    }
    /*删除元素,回调函数和内容用数组保存,调用此方法删除*/
    const deleteEl = function (arr,el) {
        let hasEl = false;
        arr.forEach((value,index) => {
            if (value === el) {
                hasEl = true;
                arr.splice(index,1);
            }
        })
        return hasEl;
    }
    /*删除命名空间*/
    const deleteNameSpace = function (nameSpace,queue) {
        return deletePropertyName(queue,nameSpace);
    }
    /*删除信息名*/
    const deleteMsgName = function (nameSpace,msgName,queue) {
        if (queue[nameSpace]) {
            return deletePropertyName(queue[nameSpace],msgName);
        }
        return false;
    }
    /*删除回调函数*/
    const deleteCallback = function (nameSpace,msgName,callback) {
        if (subscriptionQueue?.[nameSpace]?.[msgName]) {
            return deleteEl(subscriptionQueue[nameSpace][msgName],callback);
        }
        return false;
    }
    /*删除内容*/
    const deleteContent = function (nameSpace,msgName,content) {
        if (publishQueue?.[nameSpace]?.[msgName]) {
            return deleteEl(publishQueue[nameSpace][msgName],content);
        }
        return false;
    }
    /*执行新的信息队列,当发布消息时,将会执行所有对应的回调函数*/
    const implementNewMsg = function (nameSpace,msgName,content) {
        publishQueue[nameSpace][msgName].push(content);
        if (subscriptionQueue?.[nameSpace]?.[msgName]) {
            for (let fn of subscriptionQueue[nameSpace][msgName]) {
                fn(content);
            }
        }
    }
    /*执行旧的信息队列,当后订阅的回调函数想输出以前的内容,将会遍历所有对应内容,并执行此回调函数*/
    const implementOldMsg = function (nameSpace,msgName,callback){
        if (publishQueue?.[nameSpace]?.[msgName]) {
            for (let content of publishQueue[nameSpace][msgName]) {
                callback(content);
            }
        }
    }
    /*订阅
    * nameSpace: 命名空间,如果没有,则会在订阅队列中新建新建
    * msgName:信息名,如果没有,则会在订阅队列指定命名空间中新建
    * callback:回调函数,发布对应消息时,将会执行,可以重复,可接受一个参数,为对应的内容
    * oldMsg: 是否接收在订阅前发布的内容,true/false
    */
    const subscribe = function (nameSpace,msgName,callback,oldMsg) {
        createMsgName(msgName,nameSpace,subscriptionQueue);
        subscriptionQueue[nameSpace][msgName].push(callback) ;
        !!oldMsg && (implementOldMsg)(nameSpace,msgName,callback);
    }
    /*发布
    * nameSpace: 命名空间,如果没有,则会在发布队列中新建新建
    * msgName:信息名,如果没有,则会在发布队列指定命名空间中新建
    * content: 内容,可以重复
    * */
    const publish = function (nameSpace,msgName,content) {
        createMsgName(msgName,nameSpace,publishQueue);
        implementNewMsg(nameSpace,msgName,content);
    }
    /*取消订阅,根据传入形参的个数,决定删除的层级*/
    const cancelSubscribe = function (nameSpace,msgName,callback) {
        if (callback) {
            return (deleteCallback)(nameSpace,msgName,callback);
        } else if (msgName) {
            return (deleteMsgName)(nameSpace,msgName,subscriptionQueue);
        } else if (nameSpace) {
            return (deleteNameSpace)(nameSpace,subscriptionQueue);
        } else {
            return false;
        }
    }
    /*取消发布,根据传形参的个数,决定删除的层级*/
    const cancelPublish = function (nameSpace,msgName,content) {
        if (content) {
            return (deleteContent)(nameSpace,msgName,content);
        } else if (msgName) {
            return (deleteMsgName)(nameSpace,msgName,publishQueue);
        } else if (nameSpace) {
            return (deleteNameSpace)(nameSpace,publishQueue);
        } else {
            return false;
        }
    }
    return {
        subscribe,
        publish,
        cancelSubscribe,
        cancelPublish,
        [Symbol.toPrimitive] (hint) {
            return hint === 'string' ? '自定义' : true;
        }
    }
})()
//export default $intermediary
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值