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中的DSL元编程介绍

    JavaScript中的DSL元编程介绍

    这篇文章主要介绍了JavaScript中的DSL元编程介绍,本文讲解了JavaScript元编程、JavaScript eval、JavaScript new Function()等内容,需要的朋友可以参考下
    2015-03-03
  • 犀利的js 函数集合

    犀利的js 函数集合

    和同事讨论js时,我说较为理想的状态是,把js当一把好用的匕首,随手拿来,捅一刀子就走。话虽如此,但现实生活中大部分时候的情况是不理想的。
    2009-06-06
  • JavaScript截取、切割字符串的技巧

    JavaScript截取、切割字符串的技巧

    这篇文章主要介绍了JavaScript截取、切割字符串的技巧,文中给大家提到了substr 和 substring方法的区别,结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2016-01-01
  • JavaScript自定义Webpack配置实现流程介绍

    JavaScript自定义Webpack配置实现流程介绍

    本系列主要整理前端面试中需要掌握的知识点。本节介绍webpack如何优化前端性能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-10-10
  • 理解JS事件循环

    理解JS事件循环

    这篇文章主要帮助大家理解JS事件循环,深入浅出的讲解了javascript事件循环,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • javascript跨域的4种方法和原理详解

    javascript跨域的4种方法和原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
    2014-04-04
  • 用JS实现HTML标签替换效果

    用JS实现HTML标签替换效果

    用JS实现HTML标签替换效果...
    2007-06-06
  • JavaScript转换农历类实现及调用方法

    JavaScript转换农历类实现及调用方法

    农历是日常生活中不可或缺的一部分,它与人类的生活息息相关,从某种程度上说,它一直伴随着我们,今天的任务是JavaScript转换农历类的实现,感兴趣的你可以千万不要错过,希望本文对你有所帮助
    2013-01-01
  • Servlet返回的数据js解析2种方法

    Servlet返回的数据js解析2种方法

    这篇文章主要介绍了Servlet返回的数据js解析2种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 详解ECMAScript6入门--Class对象

    详解ECMAScript6入门--Class对象

    本篇文章主要介绍了详解ECMAScript6入门--Class对象,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04

最新评论