手写实现vue 发布 订阅模式和观察者模式

发布订阅模式和观察者模式

  • 发布/订阅模式
    • 订阅者
    • 发布者
    • 信号中心

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

Vue 的自定义事件

let vm = new Vue() 

vm.$on('dataChange', () => {
	console.log('dataChange')
}) 

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

vm.$emit('dataChange')

兄弟组件通信过程

// 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)
}

发布 订阅模式

  // 事件触发器
    class EventEmitter {
      constructor () {
        // { 'click': [fn1, fn2], 'change': [fn] }
        this.subs = 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.$on('fn', ()=> {
    	console.log('fn')
    })
    em.$emit('click')
    em.$emit('fn')

观察者模式

    // 发布者-目标
    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 watcher1 = new Watcher()
    let watcher2 = new Watcher()
    
    dep.addSub(watcher1)
    dep.addSub(watcher2)
    
    dep.notify()

两者的区别
在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中使用MQTT协议进行发布/订阅操作的步骤如下: 1. 安装MQTT C语言客户端库,例如Eclipse Paho或MQTT-C。 2. 创建MQTT客户端,并设置连接参数,例如服务器地址、端口、客户端ID等。 3. 连接MQTT服务器。 4. 订阅主题,可以使用subscribe函数。 5. 发布消息,可以使用publish函数。 6. 处理接收到的消息,可以使用回调函数on_message。 以下是一个使用MQTT-C库进行发布/订阅操作的简单示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "test" #define QOS 1 #define TIMEOUT 10000L volatile MQTTClient_deliveryToken deliveredtoken; void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause) { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(-1); } printf("Connected to MQTT broker at %s\n", ADDRESS); if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) { printf("Failed to subscribe to topic %s, return code %d\n", TOPIC, rc); exit(-1); } printf("Subscribed to topic %s\n", TOPIC); pubmsg.payload = "Hello, world!"; pubmsg.payloadlen = strlen(pubmsg.payload); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); printf("Message sent with delivery token %d\n", token); MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); while (1) { MQTTClient_yield(); } MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这个示例代码实现了一个MQTT客户端,它连接到本地的MQTT服务器(地址为tcp://localhost:1883),订阅主题为test,并发布一条消息(内容为“Hello, world!”)。在程序运行过程中,它会不断接收和处理从MQTT服务器上收到的消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值