javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > javascript发布-订阅模式

javascript 发布-订阅模式 实例详解

作者:flying_huixia

这篇文章主要介绍了javascript 发布-订阅模式,结合实例形式详细分析了javascript发布-订阅模式基本功能、原理、实现方法与相关使用技巧,需要的朋友可以参考下

一、核心概述

发布订阅模式主要包含三大块:缓存数组、订阅、发布

缓存数组一个数组[]
订阅往数组里面压入函数fn
发布里面循环遍历数组,然后执行数组中的函数。

二、简单代码实现及改进

(1)实现

  var subpub = {};
  subpub.cache = [];
  subpub.subscribe = function(fn){
       this.cache.push(fn)
  }
  subpub.publish = function(){
  for(var i in this.cache){
         this.cache[i].apply(this,arguments)
       }
  }
   //test
   subpub.subscribe(function(price,square){
         console.log("price:"+price)
         console.log(square)
   })
   subpub.publish(200,102);
   subpub.publish(300,153)

(2)改进 --- 主要针对订阅者不需要接收到所有的发布事件---key

 var subpub = {};
        subpub.cache = {}; //是一个数组对象
        subpub.subscribe = function (key, fn) {
            if (!this.cache[key]) { //订阅的事情在缓存里面没有,则添加到缓存
                this.cache[key] = [];
            }
            this.cache[key].push(fn);
        }
        subpub.publish = function () {
            //传入参数的第一个是指订阅的类型
            var key =  Array.prototype.splice.apply(arguments,[0,1]);
            for (var i in this.cache[key]) {
                this.cache[key][i].apply(this, arguments)
            }
        }
        //test
        subpub.subscribe('lowPrice',function (price, square) { //A订阅价格低于300的
            console.log("price:" + price)
            console.log(square)
        })
        subpub.subscribe('highPrice',function (price, square) { //B订阅价格高于300的
            console.log("price:" + price)
            console.log(square)
        })
        subpub.publish('lowPrice',200, 102);
        subpub.publish('highPrice',400, 153)

取消订阅的事件

subpub.subscribe('lowPrice', fn1 = function (price, square) { //A订阅价格低于300的
            console.log(square)
        })
        subpub.subscribe('lowPrice', fn11 = function (price, square) { //A订阅价格低于300的
            console.log("price1:" + price)
            console.log(square)
        })
        subpub.subscribe('highPrice', fn2 = function (price, square) { //B订阅价格高于300的
            console.log("price:" + price)
            console.log(square)
        })
        //取消订阅的事件
        subpub.remove = function (key, fn) {
            if (!this.cache[key]) { //如果key对应的消息没有被订阅,则直接返回
                return false
            }
            if(!fn){  //如果没有传入fn,则移除key对应的所有消息
                this.cache[key] && (this.cache[key].length=0)
            } else {
                this.cache[key] = this.cache[key].filter(function (cur, index) {
                    return cur !== fn
                })
            }
        }
        subpub.remove('lowPrice',fn1)
        subpub.publish('lowPrice', 200, 102);

取消的时候,注意区分不同情况。上述使用了filter函数用来过滤需要取消订阅的事件

三、现实项目需求

网站登录====》登录以后需要在各处显示客户的信息。不能在用户登陆后去依次调用模块的刷新或或其他相关函数,要监听登录这一次操作。

  //封装一下
        var event = {
            cache: {},
            subscribe: function (key, fn) {
                if (!this.cache[key]) { //订阅的事情在缓存里面没有,则添加到缓存
                    this.cache[key] = [];
                }
                this.cache[key].push(fn);
            },
            publish: function () {
                //传入参数的第一个是指订阅的类型
                var key = Array.prototype.splice.apply(arguments, [0, 1]);
                for (var i in this.cache[key]) {
                    this.cache[key][i].apply(this, arguments)
                }
            },
            remove: function (key, fn) {
                if (!this.cache[key]) { //如果key对应的消息没有被订阅,则直接返回
                    return false
                }
                if (!fn) { //如果没有传入fn,则移除key对应的所有消息
                    this.cache[key] && (this.cache[key].length = 0)
                } else {
                    this.cache[key] = this.cache[key].filter(function (cur, index) {
                        return cur !== fn
                    })
                }
            }
        };
        var eventForPub = function (obj) {
            for (var i in event) {
                obj[i] = event[i]
            }
        }
        var login = {};
        eventForPub(login)
        var headItem = (function () {
            login.subscribe('login', function (data) {
                headItem.setAvatar(data.avatar)
            })
            return {
                setAvatar: function (data) {
                    console.log("头部显示客户信息")
                }
            }
        })();
        var buyItem = (function () {
            login.subscribe('login', function (data) {
                buyItem.setAvatar(data.avatar)
            })
            return {
                setAvatar: function (data) {
                    console.log("购物车显示客户信息")
                }
            }
        })();
        var data={avatar:'qqqq'}
        login.publish('login',data);

运行结果如下:

更多设计模式相关知识点,还可以参考本站文章:

https://www.jb51.net/article/252965.htm

https://www.jb51.net/article/27973.htm

您可能感兴趣的文章:
阅读全文