zoukankan      html  css  js  c++  java
  • (转载)js的订阅模式

    发布-订阅模式简述

    发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。

    以网购为例:

    假设小红看上了一双鞋子,但该鞋子已经断货了,卖家承诺她到货通知。与此同时,小明、小花灯也关注了这双鞋子。

    在这个场景中,卖家就是发布者,小红等人都属于订阅者。当鞋子到货时,会依次通知到每个人。

    发布订阅模式的优点:

    1. 支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象。
    2. 发布者与订阅者耦合性降低,发布者只管发布一条消息出去,它不关心这条消息如何被订阅者使用,同时,订阅者只监听发布者的事件名,只要发布者的事件名不变,它不管发布者如何改变;同理卖家(发布者)它只需要将鞋子来货的这件事告诉订阅者(买家),他不管买家到底买还是不买,还是买其他卖家的。只要鞋子到货了就通知订阅者即可。

    发布订阅模式的缺点:

    创建订阅者需要消耗一定的时间和内存。如果过度使用的话,反而使代码不好理解及代码不好维护等等。

    如何实现发布订阅模式?

    1. 首先要想好谁是发布者(比如上面的卖家)。
    2. 然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者(比如上面的买家收藏了卖家的店铺,卖家通过收藏了该店铺的一个列表名单)。
    3. 最后就是发布消息,发布者遍历这个缓存列表,依次触发里面存放的订阅者回调函数。

    实战

    发布订阅模式是最经典的设计模式之一,介绍的文章也非常多。这里不打算过多介绍。直接上代码~~~

    var Event = (function(){
        var list = {},
              listen,
              trigger,
              remove;
              listen = function(key,fn){
                if(!list[key]) {
    				// 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
                    list[key] = [];
                }
                list[key].push(fn); // 订阅消息添加到缓存列表
            };
            trigger = function(){
                var key = Array.prototype.shift.call(arguments), // 取出消息类型名称
                     fns = list[key]; // 取出该消息对应的回调函数的集合
    			// 如果没有订阅过该消息的话,则返回
                if(!fns || fns.length === 0) {
                    return false;
                }
                for(var i = 0, fn; fn = fns[i++];) {
                    fn.apply(this,arguments); // arguments 是发布消息时附送的参数
                }
            };
            remove = function(key,fn){
    			// 如果key对应的消息没有订阅过的话,则返回
                var fns = list[key];
    			// 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅
                if(!fns) {
                    return false;
                }
                if(!fn) {
                    fns && (fns.length = 0);
                }else {
                    for(var i = fns.length - 1; i >= 0; i--){
                        var _fn = fns[i];
                        if(_fn === fn) {
                            fns.splice(i,1);// 删除订阅者的回调函数
                        }
                    }
                }
            };
            return {
                listen: listen,
                trigger: trigger,
                remove: remove
            }
    })();
    // 测试代码如下:
    Event.listen("color",function(size) {
        console.log("尺码为:"+size); // 打印出尺码为42
    });
    Event.trigger("color",42);
    

      


    作者:明易
    链接:https://juejin.im/post/5c071fd46fb9a049bd421398

  • 相关阅读:
    Git 常用命令速查表
    Android的Fragment中onActivityResult不被调用
    git基本操作
    Android混淆
    Shell
    小米手机图标应用图标不改变的问题
    linux常用基本命令
    android新建的项目界面上没有显示怎么办?
    bzoj5249: [2018多省省队联测]IIIDX(线段树)
    bzoj1951: [Sdoi2010]古代猪文(Lucas+CRT+欧拉定理)
  • 原文地址:https://www.cnblogs.com/yylingyao/p/11233235.html
Copyright © 2011-2022 走看看