优雅的发布订阅模式

126 阅读1分钟
复制就则可实现、实测有效
<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    let event = {
        // 缓存对象
        list: {},
        /**
         * 针对key添加方法
         * @method on
         * @param key 属性名
         * @param fn 方法
         * */
        on(key, fn){
            if(!this.list[key]){
                this.list[key] = [];
            }
            this.list[key].push(fn);
        },
        // 发布事件
        emit() {
            let args = [];
            for(let i = 0 ; i < arguments.length; i++){
                args.push(arguments[i]);
            };
            // 获得key
            const key = args.shift();
            // 简写方法为: const key = [].shift.call(arguments);

            // 获得方法集合
            const fns = this.list[key];
            // 判断没有情况
            if(!fns||fns.length === 0){
                return false;
            }

            fns.forEach(item => {
                item.apply(this, args);
            })
        },
        /**
         * 移除事件
         * @method remove
         * @param key 属性名
         * @param fn 方法
         * */
        remove(key, fn){
            let fns = this.list[key];
            if(!fns)return false;
            // 如果没有传对应函数的话
            // 就会将key值对应缓存列表中的函数都清空掉
            if(!fn){
                fns && (fns.length = 0);
            } else {
                // 遍历数组、将传入相同fn删除
                fns.forEach((callBack, index) => {
                    if(callBack === fn){
                        fns.splice(index, 1);
                    }
                })
            }
        }
    };
    let funcJob = (job, money) => {
        console.log(`您的职业是 ${job}`);
        console.log(`期待薪资是 ${money}`);
    };

    event.on('jobs', funcJob);
    event.emit('jobs', '前端', 12000);

    function test() {
        console.log('冲冲冲');
    }
    function deleteThing() {
        console.log('111111');
    }

    event.on('pet', data => {
        console.log('接收数据');
        console.log(data);
    });
    event.on('pet', test);
    event.on('pet', deleteThing);
    // 移除订阅
    event.remove('pet', deleteThing);
    // 发布
    event.emit('pet', ['二哈', '波斯猫']);
</script>
</body>
</html>