资讯专栏INFORMATION COLUMN

实现一个发布订阅

Aceyclee / 3060人阅读

摘要:表示事件类型回调函数,当监听的事件类型触发时,执行函数冒泡还是捕获等参数原生中,我们通过注册事件订阅,比如鼠标点击,传入回调函数在注册的事件触发时要执行的函数,那么鼠标点击时发布,传入的回调函数就会执行。

在常用的MVVM框架比如vue,组件间通信可能会有以下三种情况:

1. 父子通信:通过props
2. 非父子组件组件用eventBus通信
3. 如果项目很大,数据需要共享到多个组件(跨组件通信,改同一个数据等),用vuex管理

那么文中的eventBus是怎么实现的呢,就是根据发布订阅模式。发布订阅模式应用广泛,js事件就是一个经典的发布订阅模式。看个例子addEventListener

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行,事件目标可以是一个文档上的元素 Document 本身。
target.addEventListener(type, listener, options);
//type 表示事件类型(eg:click)
//listener 回调函数,当监听的事件类型触发时,执行listener函数
//options 冒泡还是捕获等参数

原生js中,我们通过addEventListener注册事件(订阅),比如鼠标点击,传入回调函数(在注册的事件触发时要执行的函数),那么鼠标点击时(发布),传入的回调函数就会执行。除了原生js事件。

那一个简单的发布订阅模式怎么实现呢?定义一个EventEmitter类,它有以下几个元素:

单例对象,维护订阅者:单例模式就是为保证不同的人实例化EventEmitter类之后,拿到的状态是同一个。

订阅方法:传入订阅的事件类型及回调函数,订阅事件

发布方法:传入发布的事件类型及参数(传给回调函数的),发布事件。发布时,会执行订阅时传入的回调函数

移除方法:移除订阅(监听)的回调函数

代码如下:

class EventEmitter {
            constructor(){
                //单例模式
                this._events = this._events || new Map();
            }
            //发布(触发事件)
            emit(type, ...args){
                //拿到订阅者的回调函数
                var handler = this._events.get(type);
                if(!handler){
                    return;
                }
                
                //发布时,依次执行订阅者的回调
                for(var i = 0; i< handler.length; i++){
                    handler[i].apply(this, args);
                }
            }
            //订阅(监听事件)
            addListener(type, func){
                var handler = this._events.get(type);
                
                //如果还没有同类型的订阅,新创建一个
                if(!handler){
                    this._events.set(type, [func]);
                    return;
                }
                //把回调函数塞入数组
                handler.push(func);
            }
            //移除
            removeListener(type, func){
                var handler = this._events.get(type);
                if(!handler){
                    return;
                }
                
                for(var i = handler.length; i>0; i--){
                    //找到自己要移除的函数,匿名函数不能移除
                    if(handler[i] == func){
                        handler.splice(i, 1);
                    }
                } 
            }
        }

该实现只是探究原理,异常处理之类的都没做。想了解单例模式可以看:《javaScript设计模式与开发实践》(我还没看完emmm)

参考:

[eventBus实现][2]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94105.html

相关文章

  • 发布订阅模式-实现公众号订阅/内容发布/取消订阅功能

    摘要:问观察者模式和发布订阅模式的有什么区别答一下,相信都会有满屏的结果告诉你什么是发布订阅模式,但还是希望自己通过一些例子融入去实现概念理解创建一个对象存储所有订阅者与其调用添加订阅者函数时入参有,将其存储到调用发布订阅信息函数时再根据入 问:观察者模式和发布订阅模式的有什么区别? 答:https://juejin.im/post/5a14e9... Google一下,相信都会有满屏的结果...

    XiNGRZ 评论0 收藏0
  • JavaScript 发布-订阅模式

    摘要:发布订阅模式订阅者把自己想订阅的事件注册到调度中心,当发布者发布该事件到调度中心,也就是该事件触发时,由调度中心统一调度订阅者注册到调度中心的处理代码。 发布-订阅模式,看似陌生,其实不然。工作中经常会用到,例如 Node.js EventEmitter 中的 on 和 emit 方法;Vue 中的 $on 和 $emit 方法。他们都使用了发布-订阅模式,让开发变得更加高效方便。 一...

    13651657101 评论0 收藏0
  • 订阅发布模式和观察者模式的区别

    摘要:或许以前认为订阅发布模式是观察者模式的一种别称,但是发展至今,概念已经有了不少区别。参考文章订阅发布模式和观察者模式真的不一样 首选我们需要先了解两者的定义和实现的方式,才能更好的区分两者的不同点。 或许以前认为订阅发布模式是观察者模式的一种别称,但是发展至今,概念已经有了不少区别。 订阅发布模式 在软件架构中,发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特...

    ysl_unh 评论0 收藏0
  • JavaScript 设计模式(六):观察者模式与发布订阅模式

    摘要:观察者模式维护单一事件对应多个依赖该事件的对象关系发布订阅维护多个事件主题及依赖各事件主题的对象之间的关系观察者模式是目标对象直接触发通知全部通知,观察对象被迫接收通知。 观察者模式(Observer) 观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知。 简单点:女神有男朋友了,朋友圈晒个图,甜...

    bingo 评论0 收藏0
  • JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    摘要:设计模式与开发实践读书笔记。发布订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系。附设计模式之发布订阅模式观察者模式数据结构和算法系列栈队列优先队列循环队列设计模式系列设计模式之策略模式 《JavaScript设计模式与开发实践》读书笔记。 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖它的对象都将得到通知。 例...

    muzhuyu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<