zoukankan      html  css  js  c++  java
  • js观察者模式发布/订阅

    实习期结束,最近回到学校开始学习node.js,node果然是强大。不过在涉及到文件操作的时候,发现要大量使用异步回掉操作。

    以前在写页面的时候,从没这么多异步操作,只有在使用'setInterval'和'XMLHttpRequest'时了解了一下异步编程。这次在学习node的过程中,把异步回掉算是弄清楚了。但是在编码书写代码的时候,陷入了回调金字塔(callback hell)。使用es6Promise解决了一些问题。也看到了EventProxy模块基于事件驱动的解决方案。

    在使用EventProxy的过程中,有种似曾相识的感觉。有点像观察者模式发布/订阅。首先使用数组缓存订阅者订阅的消息,当订阅者订阅消息的时候,把订阅的消息push到指定消息的队列中,当发布者发布消息的时候,我们遍历执行push到指定消息队列中的回调事件。

    而订阅者不需要关心发布者什么时候发布消息。
    而发布者不需要关心订阅者订阅的状态。

    var observer = new Observe();
    var callback = function(num) {
        console.log("event:"+num); // 输出event:2
    };
    // 订阅消息
    observer.listen("event1", callback);
    observer.listen("event2", callback);
    // 移除订阅消息1
    observer.remove('event1', callback);
    // 发布者发布消息
    observer.trigger("event1",1);
    observer.trigger("event2",2);
    

    具体代码如下:

    function Observe() {
        // 缓存订阅者的消息队列
        this._list = [];
    }
    /**
     *
     * 订阅者订阅消息
     * @param  {string}   key 消息名
     * @param  {Function} fn  回调事件
     * @return {Null}       
     */
    Observe.prototype.listen = function(key, fn) {
        if (!this._list[key]) {
            this._list[key] = [];
        }
        // 订阅消息,添加到缓存列表中
        this._list[key].push(fn);
    };
    /**
     * 
     * 移除订阅的消息
     * @param  {string}   key 消息名
     * @param  {Function} fn  回掉事件
     * @return {Null}       
     */
    Observe.prototype.remove = function(key, fn) {
        // 获取当前key下的消息记录
        var arrFn = this._list[key];
        if (!arrFn) return false;
        // 未指定fn则删除当前key下所有的订阅消息
        if (!fn) {
            arrFn.length = 0;
        } else {
            for (var i = 0; i < arrFn.length; i++) {
                if (fn === arrFn[i]) {
                    arrFn.splice(i,1);
                }
            }
        }
    };
    /**
     * 发布者发布消息
     * @param  {string} key 消息名
     * @param  {string | Object} 消息数据
     * @return {Null}  
     */
    Observe.prototype.trigger = function() {
        // 得到key,第二个及以上的参数
        var key = Array.prototype.shift.call(arguments);
        var args = arguments;
        var arrFn = this._list[key];
        if (!arrFn || arrFn.length === 0) {
            return;
        }
        // 遍历执行当前key下面的所有消息
        for (var i = 0; i < arrFn.length; i++) {
            arrFn[i].apply(this, args);
        }
    };
  • 相关阅读:
    计算机网络原理精讲第一章--基本介绍
    tensorflow基础【8】-优化器
    tensorflow基础【7】-loss function
    循环神经网络(五)-LSTM进阶
    python23的区别-日常记录
    python 多版本共存
    再谈权重共享
    循环神经网络(四)-LSTM
    循环神经网络(二)-极其详细的推导BPTT
    链式法则玩转反向传播
  • 原文地址:https://www.cnblogs.com/Aralic/p/4799372.html
Copyright © 2011-2022 走看看