【设计模式笔记4】观察者模式(发布-订阅者)

发布者不直接触及到订阅者、而是由统一的第三方来完成实际的通信的操作,叫做发布-订阅模式

Event Bus/ Event Emitter的简单实现

class EventEmitter{
    constructor(){
        // 用于存储事件,与回调函数之间的关系
        this.handlers={}
    }
    // 注册事件监听器
    on(eventName,cb) {
        // 如果没有该事件监听器,初始化一个监听器队列
        if(!this.handlers[eventName]){
            this.handlers[eventName] = []
        }
        // 去重
        if(this.handlers[eventName].indexOf(cb) === -1) {
            this.handlers[eventName].push(cb)
        }
    }
    // 触发事件监听器
    emit(eventName,...ars){
        // 检查是否有函数队列
        if(this.handlers[eventName]){
            this.handlers[eventName].forEach(cb => {
                cb(...ars)
            });
        }
    }
    //移除某个事件队列里的回调函数
    off(eventName,cb){
        let cbs = this.handlers[eventName]
        let index = cbs.indexOf(cb)
        if(index > -1) {
            cbs.splice(index,1)
        }
    }
    // 为事件注册单次监听器,(事件中的回调函数执行完后,清除)
    once(eventName,cb) {
        const wrapper = (...ars)=>{
            cb(...ars)
            this.off(eventName,wrapper)
        }
        this.on(eventName,wrapper)
    } 
}
// 匿名函数无法off
const eventemitter = new EventEmitter()
let cb1 = function(a,b){console.log(a,b)}
eventemitter.on('click2',cb1)
eventemitter.on('click2',cb1)
console.log(eventemitter.handlers['click2'])
eventemitter.on('click2',function(a,b){console.log(a,b)})
eventemitter.off('click2',cb1)
eventemitter.off('click2',function(a,b){console.log(a,b)})
console.log(eventemitter.handlers['click2'])

在Vue中使用Event Bus来实现组件间的通讯

创建一个 Event Bus(本质上也是 Vue 实例)并导出:

const EventBus = new Vue()
export default EventBus

在主文件里引入EventBus,并挂载到全局:

Vue.prototype.bus = bus

订阅事件:

this.bus.$on('someEvent', func)

触发事件:

this.bus.$emit('someEvent', params)

FaceBook推出的通用EventEmiiter库的源码

猜你喜欢

转载自www.cnblogs.com/seny-33/p/12678738.html
今日推荐