Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
conan1992 opened this issue Nov 26, 2019 · 0 comments
Open

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

conan1992 opened this issue Nov 26, 2019 · 0 comments

Comments

@conan1992
Copy link
Owner

conan1992 commented Nov 26, 2019

前言: 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant