SOURCE

/*************** 发布订阅模式 ***************/

// 事件中心
const Event = {
    // 事件队列
    events: Object.create(null),
    // 订阅者
    on: (type, cb) => {
        let events = Event.events[type]

        if (events === undefined) {
            Event.events[type] = events = []
        }
        events.push(cb)
    },
    // 发布者
    emit: (type) => {
        let events = Event.events[type]

        if (events === undefined) return
        events.forEach(cb => cb())
    },
    off: (type, cb) => {
        if (type === 'all') return Event.events = Object.create(null)

        let events = Event.events[type]

        if (events === undefined) return
        for (let i = events.length - 1; i >= 0; i--) {
            if (events[i] === cb) {
                events.splice(i, 1)
            }
        }
    }
}

// on
Event.on('click', () => {
    console.log('click 1')
})

Event.on('change', () => {
    console.log('change 1')
})

const input = () => console.log('input 1')

Event.on('input', input)

// emit
Event.emit('click')

Event.emit('change')


// off
Event.off('click', () => {
    console.log('click 1')
})

Event.off('input', input)

Event.off('all')

console.log(Event)



/*************** 观察者 ***************/

class Family {
    constructor(name, role) {
        this.name = name
        this.role = role
        // 存储观察者
        this.subs = []
    }

    publish(doing) {
        this.subs.forEach(sub => sub.cb(`${sub.subscribe.role}(${sub.subscribe.name}) 孩子(${this.name})在${doing}`))
    }
    
    subscribe(target, cb) {
        target.subs.push({
            subscribe: this,
            cb
        })
    }
}



const mom = new Family('雪殷', 'mon')
const father = new Family('重楼', 'father')
const child = new Family('地瓜', 'child')

mom.subscribe(child, (doing) => console.log(doing))
father.subscribe(child, (doing) => console.log(doing))

child.publish('做运动')
child.publish('玩王者荣耀')
console 命令行工具 X clear

                    
>
console