JS中发布订阅设计模式

俗称叫做“观察者模式”


实现思路和原理: 

1、我们先创建一个计划表(容器) 

2、后期需要做什么事情,我们都依次把需要处理的事情增加到计划表中 

3、当符合某个条件的时候,我们只需要通知计划表中的方法按照顺序依次执行即可


JQ中的发布订阅

JQ中提供了实现发布订阅设计模式的方法

let $plan = $.Callbacks();//=>创建一个计划表

let fn = function(n,m){
    //=>n=100 m=200
}
$plan.add(fn);//=>向计划表中增加方法
$plan.remove(fn);//=>从计划表中移除方法

$plan.fire(100,200);//=>通知计划表中所有的方法按照顺序执行;100 200会分别作为实参传递给每一个需要执行的方法;


封装一个类似于JQ的发布订阅模式库

我们自己基于ES6封装一个发布订阅模式库

1、基于构造函数封装 

2、模拟JQ的操作步骤 

3、注意数组塌陷问题 

4、封装EACH遍历数组中的每一项

~function () {
    //=>EACH:遍历数组中每一项的内容
    let each = function (ary, callBack) {
        for (let i = 0; i < ary.length; i++) {
            let result = callBack && callBack(ary[i], i);
            //=>如果回调函数中返回FALSE,代表结束当前正在遍历的操作(仿照JQ中的EACH语法实现的)
            if (result === false) break;
            //=>如果回调函数中返回的是DEL,代表当前这一项在回调函数中被删除了,为了防止数组塌陷问题,我们让索引减减
            if (result === 'DEL') i--;
        }
    };

    class Plan {
        constructor() {
            this.planList = [];//=>存放方法的容器
        }
        //=>挂载到PLAN原型上的方法
        add(fn) {
            let planList = this.planList,
                flag = true;
            //=>去重处理
            each(planList, function (item, index) {
                if (item === fn) flag = false;
                return flag;
            });
            flag ? planList.push(fn) : null;
        }
        remove(fn) {
            let planList = this.planList;
            each(planList, function (item, index) {
                if (item === fn) {
                    //planList.splice(index, 1);
                    //=>这样会引起数组塌陷(详情见图)
                    planList[index] = null;
                    //=>这样处理位置存在(索引在),但是值没有了
                    return false;
                }
            });
        }
        fire(...arg) {
            let planList = this.planList;
            each(planList, function (item, index) {
                if (item === null) {
                    //=>当前项是已经被REMOVE移除掉的
                    planList.splice(index, 1);
                    return 'DEL';
                }
                item(...arg);
            });
        }
        //=>挂载到PLAN对象上的属性和方法
        static Callbacks() {
            return new Plan();
        }
    }

    window.$ = window.Plan = Plan;
}();

1.png