美文网首页一个
一个例子 - 看尽并手写JS发布订阅模式

一个例子 - 看尽并手写JS发布订阅模式

作者: Jason_Zeng | 来源:发表于2019-08-03 00:14 被阅读0次

    一个系列: 一个例子看尽一个知识点

    发布订阅模式,很多地方都用到的一种模式,简单的说就是预定一件事情,时机成熟通知你,比如我们nodejs中的fs的读写文件的流,消息事件的触发等都用到了这种方式了,虽然不是特别难,但是非常实用,实现方式也简单,基本思想就是内部保存了一个对象存储订阅的函数,调用者通过名字来触发函数,订阅多个就按照队列的形式触发,下面就是具体实现

    发布订阅源码

    // 发布订阅模式
    class EventEmitter {
        constructor() {
            // 事件对象,存放订阅的名字和事件
            this.events = {};
        }
        // 订阅事件的方法
        on(eventName,callback) {
           if (!this.events[eventName]) {
               // 注意时数据,一个名字可以订阅多个事件函数
               this.events[eventName] = [callback]
           } else  {
              // 存在则push到指定数组的尾部保存
               this.events[eventName].push(callback)
           }
        }
        // 触发事件的方法
        emit(eventName) {
            // 遍历执行所有订阅的事件
           this.events[eventName] && this.events[eventName].forEach(cb => cb());
        }
        // 移除订阅事件
        removeListener(eventName, callback) {
            if (this.events[eventName]) {
                this.events[eventName] = this.events[eventName].filter(cb => cb != callback)
            }
        }
        // 只执行一次订阅的事件,然后移除
        once(eventName,callback) {
            // 绑定的时fn, 执行的时候会触发fn函数
            let fn = () => {
               callback(); // fn函数中调用原有的callback
               this.removeListener(eventName,fn); // 删除fn, 再次执行的时候之后执行一次
            }
            this.on(eventName,fn)
        }
    }
    

    使用方式

    let em = new EventEmitter();
    let workday = 0;
    em.on("work", function() {
        workday++;
        console.log("work everyday");
    });
    
    em.once("love", function() {
        console.log("just love you");
    });
    
    function makeMoney() {
        console.log("make one million money");
    }
    em.on("money",makeMoney);
    
    let time = setInterval(() => {
        em.emit("work");
        em.removeListener("money",makeMoney);
        em.emit("money");
        em.emit("love");
        if (workday === 5) {
            console.log("have a rest")
            clearInterval(time);
        }
    }, 1);
    

    输出

    work everyday
    just love you
    work everyday
    work everyday
    work everyday
    work everyday
    have a rest
    

    所以说工作五天要休息一次,赚一个亿是不可能的,但只能爱一人

    相关文章

      网友评论

        本文标题:一个例子 - 看尽并手写JS发布订阅模式

        本文链接:https://www.haomeiwen.com/subject/gddddctx.html