文档章节

发布-订阅模式

 撒哈拉大仙人掌
发布于 2016/10/08 19:28
字数 635
阅读 6
收藏 0

将发布订阅的功能提取出来,放在一个单独的对象中

var event={
    clientList:{},
    listen:function(key,fn){
        if(!this.clientList[key]){
            this.clientList[key]=[];
        }
        this.clientList[key].push(fn);
    },
    trigger:function(){
        var key=Array.prototype.shift.call(arguments),
            fns=this.clientList[key];
        if(!fns||fns.length===0){
            return false;
        }
        for (var i = 0,fn;fn = fns[i++];) {
            fn.apply(this,arguments);
        }
    },
};

var installEvent = function(obj){
    for(var i in event){
        obj[i] = event[i];
    }
}

var salesOffices = {};
installEvent(salesOffices);

salesOffices.listen('squareMeter88',function(price){
    console.log("价格="+price);
});
salesOffices.listen('squareMeter110',function(price){
    console.log("价格="+price);
});

salesOffices.trigger('squareMeter88',20000);
salesOffices.trigger('squareMeter110',30000);

取消订阅事件

//取消订阅事件
event.remove=function(key,fn){
    var fns=this.clientList[key];
    if(!fns){
        return false;
    }
    if(!fn){
        fns&&(fns.length=0);
    }else{
        for (var l = fns.length-1; l>=0; l--) {
            var _fn = fns[l];
            if(_fn === fn){
                fns.splice(l,1);
            }
        }
    }
}

应用-真实的例子-网站登录

假如我们正在开发一个商城网站,网站中有header头部、nav导航、消息列表、购物车等模块。这几个模块的渲染有一个共同的前提条件,就是必须先使用ajax异步请求获取用户的登录信息。比如用户的名字和头像要显示在header模块中,而这两个字段都来自用户登录后返回的信息。

至于ajax请求什么时候能成功返回用户信息,没有办法确定。

对用户信息感兴趣的业务模块将自行订阅登录成功的消息事件。当登陆成功时,登录模块只需要发布登录成功的消息,而业务方接受消息后,就会开始进行各自的业务处理,登录模块并不关心业务方要做什么,也不需要了解他们的内部细节。改善后的代码如下:

$.ajax('http://xxx.com?login',function() {    //登录成功
    login.trigger('loginSucc',data);        //发布登录成功的消息
});
//各模块监听成功的消息
var header=(function(){
    login.listen('loginSucc',function(data){    //header模块
        header.setAvatar(data.avatar);
    });
    return {
        setAvatar:function(data){
            console.log('设置header模块的头像');
        }
    }
})();
var nav=(function(){     //nav模块
    login.listen('loginSucc',function(data){
        nav.setAvatar(data.avatar);
    });
    return {
        setAvatar:function(avatar){
            console.log('设置nav模块的头像');
        }
    }
})();

如上所述,我们可以随时把setAvatar的方法名改成setTouxiang。如果有一天在登录完成之后,又增加一个刷新收货地址列表的行为,那么只要在收货地址模块里加上监听消息的方法即可,而这可以让开发该模块的同事自己完成,你作为登录模块的开发者,永远不用再关心这些行为了。

var address=(function(){
    login.listen('loginSucc',function(data){
        address.refresh(obj);
    });
    return {
        refresh:function(avatar){
            console.log('刷新收货地址列表');
        }
    }
})();

本人学习整理,非原创

 

 

© 著作权归作者所有

粉丝 0
博文 9
码字总数 1844
作品 0
昌平
私信 提问
iOS-观察者模式

前言 与其说发布订阅是观察者模式的别名,还不如说发布订阅本质上是一种特殊的观察者模式;两种模式都主要是用于解除一个对象与多个对象之间的耦合,即不管有多少个监听者(observer),都不...

麦兜卖鱼丸
2016/08/15
57
0
redis源码分析之发布订阅(pub/sub)

redis算是缓存界的老大哥了,最近做的事情对redis依赖较多,使用了里面的发布订阅功能,事务功能以及SortedSet等数据结构,后面准备好好学习总结一下redis的一些知识点。 先看下redis发布订阅...

凌风郎少
2017/11/05
0
0
观察者模式和发布订阅模式真的不一样?

背景 设计模式的定义: 在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。 设计模式并不能直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案,它不...

Clearlover
08/28
0
0
JavaScript设计模式系列--发布订阅模式

发布订阅模式是JavaScript设计模式系列中 特别重要的一种,特别重要,特别重要 ··· 思考一下 什么是设计模式? 设计模式是 前人总结的用于解决开发过程中某类问题的方法。 什么是设计模式...

上古神鹏
05/13
0
0
JavaScript 发布-订阅模式

发布-订阅模式,看似陌生,其实不然。工作中经常会用到,例如 Node.js EventEmitter 中的 on 和 emit 方法;Vue 中的 和 方法。他们都使用了发布订阅模式,让开发变得更加高效方便。 一、 什...

xiaoxiaobaibai
05/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JS其他类型值转化为Boolean类型规则

本文转载于:专业的前端网站➤JS其他类型值转化为Boolean类型规则 由于最近在笔试的时候,发现好多关于其他类型转化为Boolean类型的题目,因此总结一下! 一、String类型转化为Boolean 1.转化...

前端老手
10分钟前
2
0
EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClie...

Java学习录
16分钟前
2
0
析构函数是否必须为虚函数?为何?

在C++中,基类指针可以指向一个派生类的对象。如果基类的析构函数不是虚函数,当需要delete这个指向派生类的基类指针时,就只会调用基类的析构函数,而派生类的析构函数无法被调用。容易造成...

天王盖地虎626
17分钟前
2
0
【TencentOS tiny】深度源码分析(7)——事件

引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xxx_flag))这样子做...

杰杰1号
20分钟前
2
0
聊聊nacos client的ServerHttpAgent

序 本文主要研究一下nacos client的ServerHttpAgent HttpAgent nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java public interface HttpAgent { ......

go4it
27分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部