在 js 中应用 订阅发布模式(subscrib/public)

什么是发布-订阅者模式

我们在使用发布-订阅者模式之前,先了解什么是发布-订阅者模式。简单来说,发布订阅者模式就是一种一对多的依赖关系。多个订阅者(一般是注册的函数)同时监听同一个数据对象,当这个数据对象发生变化的时候会执行一个发布事件,通过这个发布事件会通知到所有的订阅者,使它们能够自己改变对数据对象依赖的部分状态。
这样看来,一个完整的订阅发布模式,由发布者、订阅者、消息管理器三部分组成。

发布-订阅者模式

我们 为什么/什么时候 要使用这种模式

首先,如果一个数据或者事件的变化会对许多事件产生影响。例如:我们通过websocket从后台实时获取数据,当返回的数据为 @end 时,需要执行关闭数据流,更改数据显示,更新设备状态等等,在不使用订阅开发者模式时,当接收到 @end 后,我们注册一个函数,需要在该函数中写n个函数的执行,但是使用设计者模式,只需要注册一个 @end 的发布函数,其他函数订阅该函数,当发布函数执行后会发布信息,其订阅者会自动更新状态。

  • 耦合性低
  • 便于代码的维护
在js中的实现

所有代码都在项目中亲测有效,且效率较高

1. 定义一个发布者对象,该对象有订阅者列表和发布函数两个属性。
function Deliver() {
  this.subscribers = [];
}
Deliver.prototype = {
  constructor: Deliver,
  deliver: function( message ) {
    this.subscribers.forEach( function( fun ) {
      fun( message );
    } );
  return this;
  }
}
2. 为发布者对象添加订阅方法和退订方法
//订阅事件
function subscribe( subscriber, deliver ) {
  var hasExists = false,
  isFunction = Object.prototype.toString.call( subscriber ) === '[object Function]';
  if( isFunction && deliver instanceof Deliver ) {
      hasExists = deliver.subscribers.some( function( fun ) {
      return fun === subscriber;
  } );
  if( !hasExists ) {
      deliver.subscribers.push( subscriber );
  }
 }
}
//退订subscriber事件
function unSubscribe( subscriber, deliver ) {
    var isFunction = Object.prototype.toString.call( subscriber ) === '[object Function]';
    if( isFunction && deliver instanceof Deliver ) {
    deliver.subscribers = deliver.subscribers.filter( function( fun ) {
        return fun !== subscriber;
	 } )
  }
 }
3. 实例化一个发布者并为其添加订阅者
var endDeliver = new endDeliver();
(function(window){
   subscriber(endHandle , endDeliver);
    subscriber(endHandle2 , endDeliver);
	if(webSocket.data == "@end"){
  			endDeliver.deliver();//当返回数据为end时,end发布者发布消息
  		}
})(window)
function endHandle(){
		console.log("已执行结束")
    }
    function endHandle2(){
	console.log("重新开始执行函数");
}
4. 运行结果

运行结果

四、应用心得
  • 可以注册一个空的发布者,即在满足某些条件时发布一些空消息,而订阅者的执行也不需要传递任何的参数。主要适用于状态的改变引起的函数执行。
  • 注册带有参数的发布者,当数据改变时,将数据作为参数传递给各个订阅者,订阅者根据返回的数据进行状态的更新。主要适用于对数据的渲染及判断。
//实例化一个数据发布者
var messagePost = new Deliver();
//该发布者有两个订阅者
subscriber(handle1 , messagePost);
subscriber(handle2 , messagePost);
//两个订阅者分别执行的函数为
function handle1(data){
	console.log(data);
}
function handle2(data){
	$(".dome").html(data.ip);
}
//在数据发生改变的时候发布者发布消息
websocket.onmessage = function(evet){
	messagePost.deliver(event.data)
}
//执行结果
当通过websocket返回的数据时,messagePost会发布消息,handle1 handle2会相继执行更新自己的数据。
第一次大规模的在项目中使用设计模式,所以把思路整理分享一下,有不对的地方还望大家能够指出。

猜你喜欢

转载自blog.csdn.net/weixin_41305441/article/details/82778648