Skip to content

3.发布-订阅模式:实现EventEmitter #4

Open
@conan1992

Description

@conan1992

前言: DOM 的事件机制就是发布订阅模式最常见的实现,这大概是前端最常用的编程模型了,监听某事件,当该事件发生时,监听该事件的监听函数被调用。

我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。(引用自阮一峰老师的《Javascript 异步编程的 4 种方法》);

话不多说,撸起袖子干。

1、EventEmitter

主要包含了 on,emit,once,off方法。

2、代码实现

class Event{
    constructor() {
        this.events = Object.create( null );
    }
    on(name, fn){
         if(!this.events[name]){
             this.events[name] = [];
         }   
         this.events[name].push(fn)
    }
    emit(name,...args){
        if(!this.events[name]){
            return this
        }
        let fns = this.events[name];
        fns.forEach(fn => {
            fn.call(this,...args)
        });
        return;
    };
    off(name, fn){
        if(!this.events[name]){
            return this
        }
        if(!fn){//如果未传函数名
            this.events[name] = null;
            return this;
        }
        const index = this.events[name].indexOf(fn);
        this.events[name].splice(index, 1);
        return this;
    };
    once(name, fn){
        const only = ()=>{
            fn.apply(this, arguments)
            this.off(name, only)
        }
        this.on(name, only);
        return;
    }
}

代码测试

<button id="btn">万花筒写轮眼</button>
let test = new Event();
let btn = document.getElementById('btn')
console.log( test )
test.on('fire', function(name){
    console.log(name)
});
test.once('fire', function(){
    console.log('螺旋丸')
})
btn.onclick = function(){
    test.emit('fire', '火遁:豪龙火之术')
}

点击按钮三次,打印情况如下:
image

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions