JavaScrip实现发布订阅模式

手写发布订阅

实现思路:

    需要有一个list对象缓存订阅事件 订阅(on)如果存在事件就往list里面缓存事件 取消订阅(off)从list对象找到订阅事件删除 发布(emit)从list对象找到事件去执行就OK 只发布一次(once)执行完删除即可

代码实现:

class EventEmitter {
          
   
    constructor(){
          
   
        // 事件缓存列表
        this.list = {
          
   }
    }
    // 订阅
    on(name,fn){
          
   
        // 如果存在事件
        if(this.list[name]) {
          
   
            this.list[name].push(fn)
        } else {
          
   
            this.list[name] = [fn]
        }
    }
    // 取消订阅
    off(name,fn){
          
   
        // 找到已经注册的事件
        let tasks = this.list[name]
        // 判断该事件是否注册
        if(tasks){
          
   
            const index = tasks.findIndex(f === fn || f.callback === fn)
            if(index>=0) {
          
   
                tasks.splice(index,1)
            }
        }
    }
    // 发布
    emit(name,once=false,...args){
          
   
        if(this.list[name]) {
          
   
            // 创建副本,如果回调函数内部继续注册相同的事件,会造成死循环
            let tasks = this.list[name].slice()
            for(let fn of tasks) {
          
   
                fn(...args)
            }
            // 如果只发布订阅一次,执行完上面代码就把事件删除
            if(once) {
          
   
                delete this.list[name]
            }
        }
    }
}

// 测试
let eventBus = new EventEmitter()
let fn1 = function(name, age) {
          
   
	console.log(`${
            
     name} ${
            
     age}`)
}
let fn2 = function(name, age) {
          
   
	console.log(`hello, ${
            
     name} ${
            
     age}`)
}
eventBus.on(aaa, fn1)
eventBus.on(aaa, fn2)
eventBus.emit(aaa, false, 布兰, 12)
Object.defineProperty
经验分享 程序员 微信小程序 职场和发展