发布-订阅者模式应用场景之websocket

文章介绍了如何在实际项目中应用发布订阅者模式,特别是在Vuex的WebSocket模块和Observer模块之间。通过创建Observer类实现消息订阅和发布功能,允许A页面订阅特定事件,当WebSocket接收到消息时发布事件,从而更新A页面的数据。Vuex的mutations中定义了订阅、取消订阅和发布事件的方法。
摘要由CSDN通过智能技术生成


一、简单的发布订阅者模式

class Observer {
  constructor() {
    this.messages = []//消息队列
  }
  /**
   * 订阅消息
   * @param {类型} type
   * @param {方法} fn
   */
  $on(type, fn) {
    if (!type) return
    !this.messages[type] && (this.messages[type] = [])
    this.messages[type].push(fn)
  }

  /**
   * 订阅一次性的消息
   * @param {类型} type
   * @param {方法} fn
   */
  $once(type, fn) {
    const self = this
    //内部执行方法
    function _on() {
      fn.apply(this, arguments) // 执行的是fn
      self.$off(type, _on) // 注意,卸载的是on函数(利用了闭包)
    }
    this.$on(type, _on)

  }
  /**
   * 取消订阅,如果不传fn则清除该类型下的所有方法
   * @param {类型} type
   * @param {要取消订阅的方法} fn
   */
  $off(type, fn) {
    if (!type) return
    if (!fn) return this.messages[type] = undefined
    this.messages[type] = this.messages[type].filter(_fn => _fn != fn)
  }

  /**
   * 发布消息
   * @param {类型} type
   * @param {参数(有时候消息队列里面的方法需要传递实参进去)} param
   */
  $emit(type, param) {
    if (!this.messages[type]) return
    this.messages[type].forEach(_fn => {
      _fn(param)
    });
  }
}


export default Observer

二、举例一个发布-订阅者模式的生产环境用途

假设一个项目中,在vuex中的一个websocket.js模块和有一个observer.js两个vuex模块;

其中websocket.js大概维护了websocket的初始化、发送消息、接收消息的方法;

然后在A页面调用,假设收到消息后,怎么在vuex中通知A页面呢?

那么就要用到发布-订阅者模式了,在A页面只负责ws发送消息的触发(但是需要传递主题type、回调函数fn),然后websocket.js的消息发送模块订阅主题,然后在websocket.js的接收ws消息的方法中发布主题,从而达到修改A页面数据的功能

observer.js

import Observer from '@/utils/Observer'
const getDefaultState = () => {
  return {
    observer: new Observer()
  }
}

const state = getDefaultState()
const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },

  //订阅消息
  OBSERVER_ON: function (state, data) {
    const { type, fn } = data
    if (type && fn) {
      state.observer.$on(type, fn)
    }
  },
  //订阅一次性消息
  OBSERVER_ONCE: function (state, data) {
    const { type, fn } = data
    if (type && fn) {
      state.observer.$once(type, fn)
    }
  },
  //取消订阅
  OBSERVER_OFf: function (state, data) {
    const { type, fn } = data
    type && state.observer.$off(type, fn)
  },
  //发布消息
  OBSERVER_EMIT: function (state, data) {
    const { type, } = data
    type && state.observer.$emit(type)
  },
}

export default {
  namespaced: true,
  state,
  mutations,
}

A页面


 
  methods: {
	start(){
      this.$store.commit("webSocket/SEND_MESSAGE", {
          type: EM.START,//使用枚举,不适用字面量
          fn: this.handleA
        });
   },
   handleA(param) {
      console.log("🚀 ~ file: electronicSignature.vue:556 ~ handleA ~ param:", param)
      this.test=param.msg
    }
   
}
       

websocket.js

	const mutations = {
		//初始化方法
		INIT_WEBSOCKETfunction(){
			...
		},
			//发送消息方法
		SEND_MESSAGEfunction(state,data){
		
			...
			//发送的时候订阅主题
			this.commit("observer/OBSERVER_ON", data)
			...
		},
			//初接收消息方法
		ON_MESSAGEfunction(state,data){
			...
			//接收的时候的时候发布主题,data里面已经和后端约定好了会有type字段的
			this.commit("observer/OBSERVER_EMIT", data)
			...
		},
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值