一分鐘理解 JavaScript 發佈訂閱模式

前端時空前端

前端網紅集結號,傳遞一線全棧技術,帶你穿越前端時空。編程


發佈訂閱模式,由觀察者模式衍化而來,定義了對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都將獲得通知,並自動更新。與發佈訂閱模式不一樣的是,觀察者模式的區別在於訂閱者與發佈者具備直接依賴關係,而發佈訂閱模式由一箇中間人進行消息的統一調度。咱們先從觀察者模式開始。bash

觀察者模式

引一個生動的小例子,王和小李知道張三是賣報的夥計,他們都想在張三那裏買報紙。小王和小李便和張三約定,一旦張三有了新報紙,就通知他倆。這裏,小王和小李做爲觀察者,張三做爲被觀察者,張三和王、李創建起一對多的通信關係。此時一旦有消息發佈,依賴於被觀察者的對象都將獲得通知,並自動更新。框架


下面 p一、p二、p3 分別表明王、李、張三。函數式編程

function Person(name) {
    this.name = name;
    this.list = []
}
Person.prototype.publish = function (money){
    console.log(this.name + '賣報一份'+money+"元")
    this.list.forEach(function(item, index){
        item(money)
    })
}
Person.prototype.subscribe  = function (targrt,fn){
    console.log(this.name + '準備買' + targrt.name+'的報紙');
    targrt.list.push(fn)
}
let p1 = new Person('p1')
let p2 = new Person('p2')
let p3 = new Person('p3')
p1.subscribe(p3 ,(money)=>{
    console.log(money >= 100 ? '太貴了,不買' : '買一份');
})
p2.subscribe(p3 ,(money)=>{
    console.log(money >= 200 ? '太貴了,不買' : '買一份');
})
p3.publish(120)複製代碼


                                          


張三發佈了120元的報紙。王、李根據自身狀況當即作出響應。函數

發佈訂閱模式


發佈訂閱模式的不一樣在於,觀察者訂閱者和訂閱目標是聯繫在一塊兒的,也就是王、李、張都是熟人,互相有聯繫。ui


而在發佈訂閱模式中,稱爲發佈者的消息發送者不會將消息直接發送給訂閱者,這意味着發佈者和訂閱者不知道彼此的存在。在發佈者和訂閱者之間存在第三個組件,稱爲消息代理或調度中心或中間件,它維持着發佈者和訂閱者之間的聯繫,過濾全部發布者傳入的消息並相應地分發它們給訂閱者。this


也就是說,如今的小王、小李,開始在報社訂閱報紙了,張三也把本身的報紙賣到報社,由報社進行銷售。這個報社,就是調度中心。訂閱和發佈事件,由這個調度中心統一管理。spa


let Topic = {
    topics: {},
    subscribe(topic, fn) {
        if (!this.topics[topic]) {
            this.topics[topic] = []
        }
        this.topics[topic].push(fn)
    },
    publish(topic, money) {
        if (this.topics[topic]) {
            for (let fn of this.topics[topic]) {
                fn(money)
            }
        }
    }
}
function Person(name) {
    this.name = name
}
Person.prototype.subscribe = function (topic, fn) {
    console.log('訂閱者' + this.name + '訂閱了' + topic )
    Topic.subscribe(topic, fn)
}
Person.prototype.publish = function (topic, money) {
    console.log('發佈者' + this.name + '發佈了' + topic )
    Topic.publish(topic, money)
}
let p1 = new Person('p1')
let p2 = new Person('p2')
let p3 = new Person('p3')
p1.subscribe('北京日報',(money)=>{
    console.log(money >= 100 ? '太貴了,不買' : '訂閱');
})
p2.subscribe('上海日報',(money)=>{
    console.log(money >= 200 ? '太貴了,不買' : '訂閱');
})
p2.subscribe('北京日報',(money)=>{
    console.log('訂閱');
})
p3.publish('北京日報', 198)複製代碼



此時,三位訂閱者經過 topic 訂閱報紙,報社經過 topic 自動觸發來發布報紙。prototype


尾聲

JavaScript 發佈訂閱模式得益於函數式編程中的高階函數概念,它具備十分普遍的應用。JavaScript Vue 框架的就採用了這種設計理念。Vue 框架利用 Object.defineProperty + 發佈訂閱模式實現了雙向綁定。Observer、Dep、Watcher 就充當了發佈者、topic、訂閱者。感興趣的小夥伴,能夠繼續關注咱們喲。


                                      

相關文章
相關標籤/搜索