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

 更新时间:2023年06月28日 09:06:24   作者: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

相关文章

  • javascript比较两个日期的先后示例代码

    javascript比较两个日期的先后示例代码

    这篇文章主要介绍了javascript比较两个日期的先后示例代码,非常的不错,这里推荐给有相同需求的小伙伴。
    2014-12-12
  • Bootstrap模态对话框中显示动态内容的方法

    Bootstrap模态对话框中显示动态内容的方法

    今天小编就为大家分享一篇Bootstrap模态对话框中显示动态内容的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 原生JS实现多个小球碰撞反弹效果示例

    原生JS实现多个小球碰撞反弹效果示例

    这篇文章主要介绍了原生JS实现多个小球碰撞反弹效果,结合完整实例形式分析了javascript实现小球碰撞的相关数值计算、随机数生成、事件响应等操作技巧,需要的朋友可以参考下
    2018-01-01
  • javascript中mouseenter与mouseover的异同

    javascript中mouseenter与mouseover的异同

    javascript中mouseover和mouseenter的区别主要在于监听对象的子元素是否触发事件。mouseover:鼠标移入监听对象中,或者从监听对象的一个子元素移入另一个子元素中时触发该事件。mouseenter:鼠标移入监听对象时触发,在监听对象内移动不会触发。
    2017-06-06
  • js实现滑动轮播效果

    js实现滑动轮播效果

    这篇文章主要为大家详细介绍了js实现滑动轮播效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Javascript动态创建div的方法

    Javascript动态创建div的方法

    这篇文章主要介绍了Javascript动态创建div的方法,是javascript节点操作的典型应用,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • bootstrap weebox 支持ajax的模态弹出框

    bootstrap weebox 支持ajax的模态弹出框

    本篇介绍的bootstrap weebox(支持ajax的模态弹出框),历经多次修改,目前版本已经稳定,整合了bootstrap的响应式,界面简单,功能却无比丰富,支持ajax、图片预览等等
    2017-02-02
  • 前端使用domtoimage生成截图的详细步骤

    前端使用domtoimage生成截图的详细步骤

    前端生成截图技术多样,html2canvas虽详细但耗时且阻塞操作,而domtoimage使用流畅,支持多种图片格式转换,如png、jpg、svg等,并可获取原始像素值,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • JS如何根据条件取出数组中对应项

    JS如何根据条件取出数组中对应项

    这篇文章主要介绍了JS根据条件取出数组中对应项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 屏蔽IE弹出"您查看的网页正在试图关闭窗口,是否关闭此窗口"的方法

    屏蔽IE弹出"您查看的网页正在试图关闭窗口,是否关闭此窗口"的方法

    本篇文章主要是对屏蔽IE弹出"您查看的网页正在试图关闭窗口,是否关闭此窗口"的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12

最新评论