精华内容
下载资源
问答
  • 主要介绍了JavaScript事件发布/订阅模式,结合实例形式简单分析了javascript发布/订阅模式的概念、原理及简单使用方法,需要的朋友可以参考下
  • 主要介绍了JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法,结合实例形式分析了JavaScript观察者模式概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下
  • 订阅发布模式由三部分构成 1:订阅者 2:事件中心 3:发布者 具体实现流程 发布发布消息给事件中心 事件中心通知所有的订阅者 案例1: 家长都想知道自己孩子在学校的成绩 因此老师就创建了一个群来告知家长学习...

    订阅发布模式由三部分构成

    1:订阅者
    2:事件中心
    3:发布者
    具体实现流程 发布者发布消息给事件中心 事件中心通知所有的订阅者

    案例1:

    家长都想知道自己孩子在学校的成绩 因此老师就创建了一个群来告知家长学习成绩 在这里 家长就是订阅者 群 就相当于是实践中心 而老师就是发布者 老师只需要向群(事件中心)发布消息 所有的家长都能得知消息 这就是订阅发布模式

    案例2

    vue中的自定义事件
    在自定义事件中 new一个vue实例 这个实例 就相当于我们的事件中心 o n 注 册 事 件 在 这 里 就 是 订 阅 者 而 on注册事件 在这里就是订阅者 而 onemit 在这里就相当于是发布者 在某个时候触发 e m i t 就 会 通 知 所 有 的 订 阅 者 即 emit 就会通知所有的订阅者 即 emiton注册的相同事件的函数 具体看代码

     let vm =new Vue();
        vm.$on('dataChange',()=>{
            console.log('dataChange1')
        })
        vm.$on('dataChange',()=>{
            console.log('dataChange2')
        })
        vm.$emit('dataChange')
    

    案例3:

    vue组件中的组件通信 bus

      // 事件中心
        let eventBus = new Vue()
        // componentA 组件A  
        // 这里我们作为发布者
        addToto(){
            // 发布消息事件
            eventBus.$emit('add-todo',{name:'xiaogao'})
        }
        // componentB  组件B
        // 订阅者 
        created(){
            // 订阅消息 事件
            eventBus.$on('add-to',this.addToto)
        }
    

    vue对象订阅发布模式的模拟实现

    在vue中 o n 是 订 阅 者 用 来 注 册 事 件 这 些 被 注 册 事 件 中 的 函 数 需 要 存 储 事 件 中 心 这 里 我 们 用 s u b s 表 示 事 件 中 心 因 为 相 同 的 事 件 可 以 注 册 不 同 的 函 数 故 我 们 的 事 件 中 心 是 一 个 对 象 键 值 对 的 形 式 并 且 每 个 键 值 应 该 是 换 一 个 数 组 的 形 式 而 on 是订阅者 用来注册事件 这些被注册事件中的函数需要存储事件中心 这里我们用subs表示事件中心 因为相同的事件可以注册不同的函数 故我们的事件中心是一个对象键值对的形式 并且每个键值应该是换一个数组的形式 而 onsubsemit是发布者 用来触发事件 具体代码实现如下

    class EventEmitter {
            constructor() {
                this.subs = Object.create(null);//Object.create创建对象 有原型对象 这里参数值为null 表无原型对象 仅仅是创建一个空对象
            }
            // 注册事件
            $on(eventType, handler) {
                this.subs[eventType] = this.subs[eventType] || [];
                this.subs[eventType].push(handler);
    
            }
             // 触发事件
            $emit(eventType) {
                if (this.subs[eventType]) {
                    this.subs[eventType].forEach(handler => {
                        handler();
                    });
                }
            }
        }
        let em = new EventEmitter();
        em.$on('click',()=>{console.log('click1')})
        em.$on('click',()=>{console.log('click2')})
        em.$emit('click')
    

    下一篇 我讲解观察模式

    展开全文
  • 主要介绍了JavaScript设计模式之观察者模式与发布订阅模式,结合实例形式详细分析了JavaScript观察者模式与发布订阅模式相关概念、原理
  • 主要介绍了JavaScript实现与使用发布/订阅模式,较为详细的分析了发布/订阅模式的概念、原理并结合实例形式分析了javascript实现与使用发布/订阅模式的相关操作技巧,需要的朋友可以参考下
  • 发布订阅模式 应用场景:vue事件监听(兄弟组件之间传递数据)、nodejs事件监听 成员: 发布者:在发布者中调用 notify() 订阅者:在订阅者中调用 addSub() 事件中心:subs数组、addSub()(也对应on)、notify()...

    发布订阅模式

    应用场景:

    vue兄弟组件之间数据传递、nodejs事件监听

    主要成员:

    1. 发布者: 在发布者中调用 hub.notify(),或名为 emit()

    2. 订阅者: 在订阅者中调用 hub.addSub(),或名为 on()

    3. 事件中心:

    • hub.subs数组,用于存储所有订阅者;
    • hub.addSub(),用于添加订阅到subs数组,参数为订阅名称、回调函数;
    • hub.notify(),用于发布消息通知所有订阅执行更新方法:hub.update()
    // vue 兄弟组件之间数据传递伪代码
    // 事件中心 eventHub 
    let eventHub = new Vue()
    
    // 组件A:发布者
    addTodo: function (){
        eventHub.$emit('add-todo', { text: this.newTodoText })
        this.newTodoText = ''
    }
    
    // 组件B:订阅者
    created: function (){
        eventHub.$on('add-todo',(e)=>{ })
    }
    

    主要特点:

    添加订阅、发布消息都是用的事件中心里面的方法,且数据存储和数据更新都是用的事件中心里面的方法;所以真正的观察者和发布者之间没有耦合。

    示例代码:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>发布订阅模式</title>
        <meta name='viewport' content='width=device-width, initial-scale=1'>
    </head>
    
    <script>
    
        // 发布订阅模式事件中心类
        class PublishSubscribe{
            constructor(){
                this.subs = {} // Object.create(null)
            }
            // 订阅
            addSub(eventType, handler) {
                this.subs[eventType] = this.subs[eventType] || []
                this.subs[eventType].push(handler)
            }
            // 发布
            notify(eventType){
                if(this.subs[eventType]){
                    this.subs[eventType].forEach(handler => {
                        handler()
                    })
                }
            }
        }
    
        // 发布订阅模式使用示例
        // 1、vm 为事件中心实例对象
        let vm = new PublishSubscribe()
    
        // 2、订阅消息(在订阅者中调用,例如某个组件1中)
        vm.addSub("click",()=>{
            console.log("click1")
        })
    
        vm.addSub("click",()=>{
            console.log("click2")
        })
    
        vm.addSub("change",()=>{
            console.log("change1")
        })
    
        // 3、发布消息(在发布者中调用,例如某个组件2中)
        vm.notify("click")
        vm.notify("change")
    
    </script>
    <body>
        
    </body>
    </html>
    
    

    观察者模式

    应用场景

    vue 双向绑定实现原理

    主要成员

    1. 发布者 ,发布者为一个对象

    • dep.subs数组,用于存储所有订阅者
    • dep.addSub()方法,用于添加订阅到subs数组,参数为观察者实例:watcher
    • dep.notify()方法,用于发布消息通知所有订阅者们执行更新方法:update()

    2. 订阅者/观察者 ,订阅者为一个对象

    • watcher.update()方法,用于更新执行消息发布后的更新;可以将某个callback()传递给update()
    let dep = new Dep() // 发布者实例化
    let watcher = new Watcher() // 观察者实例化
    
    dep.addSub(watcher) // 添加订阅
    dep.notify() // 不发通知
    

    主要特点

    添加订阅的时候使用 dep.addSub(watcher)、以及发布订阅的时候使用 dep.notify() 通知所有的 watcher 执行 watcher.update();所以发布者和订阅者之间存在依赖;

    示例代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>观察者模式</title>
        <meta name='viewport' content='width=device-width, initial-scale=1'>
    </head>
    
    <script>
        // 1、发布者
        class Dep{
            constructor(){
                this.subs = []
            }
    
            addSub (sub){
                if(sub && sub.update)
                    this.subs.push(sub)
            }
    
            notify (){
                this.subs.forEach(sub => sub.update())
            }
        }
        // 2、订阅者、观察者
        class Watcher{
            constructor(name){
                this.name = name
            }
            update(){
                console.log("update:", this.name)
            }
        }
    
        // 使用观察者模式
        let watcher1 = new Watcher("观察者1")
        let watcher2 = new Watcher("观察者2")
        let dep = new Dep()
    
        dep.addSub(watcher1)
        dep.addSub(watcher2)
        dep.notify()
    
    </script>
    <body>
        
    </body>
    </html>
    

    发布订阅、观察者模式的区别?

    发布订阅模式

    1. 有事件中心、发布者、订阅者三个成员;(事件中心的作用可以隔离发布者和订阅者,去除他们之间的依赖)
    2. 事件中心有三个成员:

    • subs => 存储订阅者
    • addSub() 方法 => 添加订阅者
    • notify() 方法 => 通知订阅者更新的
    • update() 方法 => 执行更新回调等功能

    3. 发布和订阅者是抽象的,通常是在某个方法里调用 addSub() 和 notify() 。

    观察者模式

    1. 没有事件中心,只有发布者、订阅者两个成员;
    2. 发布者中有三个成员:

    • subs => 存储订阅者
    • addSub() 方法 => 添加订阅者
    • notify() 方法 => 通知订阅者更新的

    3. 订阅者中必须有一个成员:

    • update() 方法 => 执行更新回调等功能

    4. 发布和订阅者是一个对象。

    在这里插入图片描述
    特别鸣谢:拉勾教育前端高薪训练营;

    展开全文
  • 发布/订阅模式 订阅者 发布者 信号中心 我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心发布(publish)一个信号,其他任务可以向信号中心订阅(subscribe)这个信号,从而知道什么时候自己可以...

    发布/订阅模式

    • 订阅者
    • 发布者
    • 信号中心

    我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心发布(publish)一个信号,其他任务可以向信号中心订阅(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做“发布/订阅模式”(publish-subscribe pattern)

    常见的发布/订阅模式:Vue
    的自定义事件
    、node的事件处理机制。

    
    let vm = new Vue()
    vm.$on('dataChange', () => { console.log('dataChange')
    })
    vm.$on('dataChange', () => { console.log('dataChange1')
    }) vm.$emit('dataChange')
    

    在vue中vue实例既是发布者,也是订阅者,又是消息中心。

    • 兄弟组件通信过程:
    
    // eventBus.js
    // 事件中心
    let eventHub = new Vue()
    // ComponentA.vue
    // 发布者
    addTodo: function () {
    // 发布消息(事件)
    eventHub.$emit('add-todo', { text: this.newTodoText }) this.newTodoText = ''
    }
    // ComponentB.vue
    // 订阅者
    created: function () {
    // 订阅消息(事件)
    eventHub.$on('add-todo', this.addTodo) }
    

    模拟vue中的事件发布机制(发布定义模式)

    • 分析:
    1. 定义一个事件发布机制类
    2. 具有$emit方法用于发布事件,会执行。
    3. 具有$on方法用于订阅事件,可以多次订阅相同事件,订阅时不会执行方法
    • 实现:
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <script>
          
          class EventEmitter {
            constructor() {
    					// 用于存储所有的注册事件
              this.subs = Object.create(null);
            }
            // 注册事件
            $emit(eventType) {
    					// 为了简便,不考虑参数的情况
              if (this.subs[eventType]) {
                this.subs[eventType].forEach((item) => {
                  item();
                });
              }
            }
            // 触发事件
            $on(eventType, handler) {
              this.subs[eventType] = this.subs[eventType] || [];
              this.subs[eventType].push(handler);
            }
          }
    
          // 测试
          let em = new EventEmitter();
          em.$on("click", () => {
            console.log("click1");
          });
          em.$on("click", () => {
            console.log("click2");
          });
    
          em.$emit("click");
        </script>
      </body>
    </html>
    
    

    观察者模式

    • 观察者(订阅者)-watcher

      • update():当事件发生时,具体要做的事情
    • 目标(发布者) – Dep

      • subs 数组:存储所有的观察者
      • addSub():添加观察者 notify():当事件发生,调用所有观察者的 update() 方法
    • 没有事件中心

    • 常用场景:Vue.js的响应机制中使用了观察者模式。

    模拟vue的响应机制(观察者模式)

    • 分析:

    1.定义一个发布者响应类和一个观察者订阅类
    2.具有addSub方法用于新增订阅后将方法添加到subs数组中
    3.具有notify方法用于发布后通知所有订阅者调用他们的update方法

    • 实现:
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1.0">
    	<title>Document</title>
    </head>
    <body>
    	<script>
    		
    		// 发布者-目标
        class Dep {
          constructor () {
            // 记录所有的订阅者
            this.subs = []
          }
          // 添加订阅者
          addSub (sub) {
            if (sub && sub.update) {
              this.subs.push(sub)
            }
          }
          // 发布通知
          notify () {
            this.subs.forEach(sub => {
              sub.update()
            })
          }
        }
        // 订阅者-观察者
        class Watcher {
          update () {
            console.log('update')
          }
        }
    
        // 测试
        let dep = new Dep()
        let watcher = new Watcher()
    
        dep.addSub(watcher)
    
        dep.notify()
    
    	</script>
    </body>
    </html>
    

    发布订阅模式与观察者模式对比

    • 观察者模式是由具体目标调度,比如当事件触发,Dep 就会去调用观察者的方法,所以观察者模
      式的订阅者与发布者之间是存在依赖的。

    • 发布/订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。事件中心隔离了发布者与订阅者,减少了互相依赖的关系。
      在这里插入图片描述

    展开全文
  • 发布订阅模式,也可以称之观察者模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。发布订阅模式与观察者模式也有着些许区别。请看下面。 观察...

    首先声明,本文的创作灵感和基础来源于 这篇文章

    发布订阅模式,也可以称之观察者模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。发布订阅模式与观察者模式也有着些许区别。请看下面。

    观察者模式

    小王和小李知道张三是卖报的伙计,他们都想在张三那里买报纸。小王和小李便和张三约定,一旦张三有了新报纸,就通知他俩。这里,小王和小李作为观察者,张三作为被观察者,张三和王、李建立起一对多的通讯关系。此时一旦有消息发布,依赖于被观察者的对象都将得到通知,并自动更新。

    下面p1、p2代表王、李,p3代表张三。

    function Person(name) {
        this.name = name;
        this.list = []
    }
    Person.prototype.publish = function (money){
        console.log(this.name + '卖报一份'+money+"元")
        this.list.forEach(function(item, index){
            item(money)
        })
    }
    Person.prototype.subscribe  = function (targrt,fn){
        console.log(this.name + '准备买' + targrt.name+'的报纸');
        targrt.list.push(fn)
    }
    let p1 = new Person('p1')
    let p2 = new Person('p2')
    let p3 = new Person('p3')
    
    p1.subscribe(p3 ,(money)=>{
        console.log(money >= 100 ? '太贵了,不买' : '买一份');
    })
    p2.subscribe(p3 ,(money)=>{
        console.log(money >= 200 ? '太贵了,不买' : '买一份');
    })
    p3.publish(120)
    

    张三发布了120元的报纸。 王、李立即做出响应。
    在这里插入图片描述

    订阅发布模式

    订阅发布模式的不同在于,观察者订阅者和订阅目标是联系在一起的,也就是王、李、张都是熟人,互相有联系。

    发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。 引用片段来源

    也就是说,现在的小王、小李,开始在报社订阅报纸了,张三也把自己的报纸卖到报社,由报社进行销售。这个报社,就是 调度中心。订阅和发布事件,由这个调度中心统一管理。

    let Topic = {
        topics: {},
        subscribe(topic, fn) {
            if (!this.topics[topic]) {
                this.topics[topic] = []
            }
            this.topics[topic].push(fn)
        },
        publish(topic, money) {
            if (this.topics[topic]) {
                for (let fn of this.topics[topic]) {
                    fn(money)
                }
            }
        }
    }
    
    function Person(name) {
        this.name = name
    }
    
    Person.prototype.subscribe = function (topic, fn) {
        console.log('订阅者' + this.name + '订阅了' + topic )
        Topic.subscribe(topic, fn)
    }
    Person.prototype.publish = function (topic, money) {
        console.log('发布者' + this.name + '发布了' + topic )
        Topic.publish(topic, money)
    }
    
    let p1 = new Person('p1')
    let p2 = new Person('p2')
    let p3 = new Person('p3')
    
    p1.subscribe('北京日报',(money)=>{
        console.log(money >= 100 ? '太贵了,不买' : '订阅');
    })
    p2.subscribe('上海日报',(money)=>{
        console.log(money >= 200 ? '太贵了,不买' : '订阅');
    })
    p2.subscribe('北京日报',(money)=>{
        console.log('订阅');
    })
    p3.publish('北京日报', 198)
    
    

    在这里插入图片描述


    有没有豁然开朗。哈哈。

    展开全文
  • JS 基础篇(发布订阅模式)

    万次阅读 2020-01-20 18:30:21
    发布订阅模式js文件 //发布者 var eventObj = { //缓存列表,存放订阅者的信息 list:{}, //添加订阅 listen:function(key,fn){ if(!this.list[key]){ this.list[key] = []; } typeof fn==='...
  • 数据模型仅仅是普通的 JavaScript 对象,而当我们修改数据时,视图会进行更新,避免了繁琐的 DOM 操作,提高开发效率。 双向绑定 数据改变,视图改变;视图改变,数据也随之改变 我们可以使用 v-model 在表单元素...
  • 1. 什么是观察者模式/发布-订阅模式? 2. 观察者模式的实现 3. 发布-订阅模式的实现 4. Vue中的发布-订阅模式 4.1 EventBus 4.2 Vue源码 5. 观察者模式的优缺点 6. 发布-订阅模式的优缺点
  • JS中的发布-订阅模式

    千次阅读 2019-03-13 17:19:43
    vue.js 是采用数据劫持结合发布者-订阅模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter, 在数据变动时发布消息给订阅者,触发相应的监听回调。 三、什么是发布-订阅模式 多个订阅者...
  • JS之观察者模式和发布订阅模式二者工作原理&区别观察者模式发布订阅模式区别发布订阅模式的代码实现参考 二者工作原理&区别 观察者模式 如同实验进行的过程一般,观察者和被观察者(目标)是紧耦合的,如果...
  • 要搞清楚vue中的双向数据绑定原理,就必须理解什么是发布订阅模式!! 1、首先想好谁是发布者、谁是订阅者(例如NBA专栏就是发布者,NBA球迷就是订阅者) 2、然后给发布者添加一个缓存列表,用于存放回调函数...
  • JS事件发布订阅原理

    千次阅读 2017-06-21 16:49:27
    学过nodeJS的人, 对eventEmmit这个包应该很熟悉吧…它采用的是事件发布订阅模式. eventEmmit可以自定义事件名, 并跟某些特定的元素绑定. 而本文抛弃nodeJS包, 尝试从自己的角度剖析这个神器的内在. 原生JS有一个...
  • 发布订阅原理实现

    千次阅读 2019-10-19 16:17:21
    1.发布订阅在很多地方很常见,其原理就是把想要执行的方法放到数组里面去,然后遍历数组执行里面的方法 其中把方法添加到数据叫订阅 遍历数组执行里面的方法叫发布 接下来,上代码 //发布订阅 function Dep(){ ...
  • 在开始分析代码之前先了解一下JavaScript的设计模式之发布-订阅模式,观察者模式 什么是发布-订阅模式 代码分析大致分为三部分:让数据变成响应式、依赖收集 和 派发更新。 让数据变成响应式 什么是数据响应式?...
  • zh众所周知,vue2.x版本是通过Object.defineProperty() 种的get进行拦截,set进行发送,其实这只是表面理解,实际运用的是JavaScript订阅者、发布模式。首先,了解一下什么是订阅者、发布模式 吧。w3c 上是...
  • 订阅发布模式的介绍 发布订阅模式,它定义了一种一对多的关系,可以使多个观察者对象对一个主题对象进行监听,当这个主题对象发生改变时,依赖的所有对象都会被通知到。 在生活中我们常常遇到这样一种情况,我们在.....
  • js发布订阅模式

    2019-08-26 18:02:54
    原理很简单:有20个人订了牛奶,每天新牛奶也来后,送奶工依次送到订奶客户的手里,,,,,,, 代码如下: //存放订阅事件数组 var _events = []; class eventEmit { //绑定订阅事件 on(eventname,cb){ if...
  • 关于发布订阅模式,可以先参考此篇文章:《javascript 发布订阅模式》。 先创建一个统筹全局事件的类 // 调度中心 class EventCenter{ constructor(){ this.eventCenter = {}; // 创建一个事件中心,数据模型:{...
  • 在众多设计模式中,可能最常见、最有名的就是发布 - 订阅模式了,本篇我们一起来学习这个模式。 发布 - 订阅模式(Publish-Subscribe Pattern, pub-sub)又叫观察者模式(Observer Pattern),它定义了一种一对多的...
  • 概念 发布-订阅模式又叫观察者模式。它定义对象间的一种一对多关系,当一个对象的状态发生变化时,所有依赖于它的对象都将得到通知...确实,在JavaScript语言中,DOM事件、Event对象、Proxy对象等都是发布-订阅模式
  • JavaScript发布者-订阅模式

    千次阅读 2019-05-03 20:26:53
    发布者-订阅模式又称观察者模式:当一个对象(发布者)状态发生改变时,所有依赖它的对象(订阅者)都会得到通知。 该模式广泛应用在异步编程中:我们无需关注对象在异步运行期间的内部状态,只需要订阅感兴趣的...
  • 前端工程师进阶学习设计模式,深入学习发布订阅模式原理
  • 主文件2.vue.js(模拟vue实例,进行数据代理)3.observer.js(数据劫持)4.eventEmitter.js(发布订阅操作)5.compiler.js (编译模板) 1.主文件 <!DOCTYPE html> <html lang="en"> <head> <meta...
  • 最近在看vue的源码,发现用到了js发布订阅模式,所以就恶补了一下,这。。。到底是个啥? 说到发布订阅模式,我看到很多人将它和观察者模式说成一个,看了这么多的博文介绍,我还是倾向于他们两个是两种模式。...
  • 上一篇讲到观察者模式,这篇要讲下发布-订阅模式。 有人可能会说了:这两个不是一回事吗?确实这两个模式的核心思想、运行机制上没有本质的差别。 但还是有些差别,要不然我这篇要讲啥,且听我娓娓道来 生活中的发布...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,596
精华内容 6,238
关键字:

js发布订阅模式原理