Skip to content

发布订阅与观察者模式

🕒 Published at:

在当前的 JavaScript 库中,发布订阅和观察者模式是非常常见的两种设计模式。

发布订阅模式

发布订阅模式主要分为两个部分 on (订阅) 与 emit (发布),on会把用户提供的回调函数保存,当 emit 时,执行用户的函数。

js
const e = {
    _obj:{},
    _callback:[],
    on(fn){
        this._callback.push(fn)
    },
    emit(key,value){
        this._obj[key] = value
        this._callback.forEach(fn=>{
            fn(this._obj)
        })
    }
}

e.on(obj=>{
    console.log(obj) // {learn:'js'}
})

setTimeout(()=>{
    e.emit('learn' , 'js')
},1000)
const e = {
    _obj:{},
    _callback:[],
    on(fn){
        this._callback.push(fn)
    },
    emit(key,value){
        this._obj[key] = value
        this._callback.forEach(fn=>{
            fn(this._obj)
        })
    }
}

e.on(obj=>{
    console.log(obj) // {learn:'js'}
})

setTimeout(()=>{
    e.emit('learn' , 'js')
},1000)

发布订阅的特点是会把用户订阅时的回调函数和发布时的键值对储存在第三方,订阅方和发布方之间没有直接关系。

观察者模式

观察者模式存在两个角色,观察者和被观察者。

js
class Observer {  //观察者
    constructor(name){
        this.name = name
    }

    update(s){
        console.log(`${this.name},${s.name}的心情是${s.state}`)
    }
}

class Subject { //被观察者
    constructor(name){
        this.name = name
        this.state = '开心'
        this.observers = []
    }
    attach(o){
        this.observers.push(o)
    }
    setState(s) {
        this.state = s
        this.observers.forEach(o=>{
            o.update(this)
        })
    }
}

const bady = new Subject('宝宝')
const father = new Observer('爸爸')
const mather = new Observer('妈妈')
bady.attach(father)
bady.attach(mather)

setTimeout(()=>{
    bady.setState('不开心')
    // "爸爸,宝宝的心情是不开心"
    // "妈妈,宝宝的心情是不开心"
}, 1000)
class Observer {  //观察者
    constructor(name){
        this.name = name
    }

    update(s){
        console.log(`${this.name},${s.name}的心情是${s.state}`)
    }
}

class Subject { //被观察者
    constructor(name){
        this.name = name
        this.state = '开心'
        this.observers = []
    }
    attach(o){
        this.observers.push(o)
    }
    setState(s) {
        this.state = s
        this.observers.forEach(o=>{
            o.update(this)
        })
    }
}

const bady = new Subject('宝宝')
const father = new Observer('爸爸')
const mather = new Observer('妈妈')
bady.attach(father)
bady.attach(mather)

setTimeout(()=>{
    bady.setState('不开心')
    // "爸爸,宝宝的心情是不开心"
    // "妈妈,宝宝的心情是不开心"
}, 1000)

观察者模式中,观察者和被观察者之间是有关系的。当被观察者状态发生变化时,会通知所有的观察者。

--- Done ---