天天看點

訂閱釋出和觀察者模式釋出訂閱模式觀察者模式

釋出訂閱模式

把多個方法暫存起來,最後一次觸發執行
  • 作用: 解偶
  • 使用場景: 如,多個類或者函數内,可以分散訂閱某個操作,最後統一釋出。分散的好處就是不做代碼侵入,各自為政,實作代碼低耦合。
  • 幾乎所有的庫,都會有基于該設計模式的功能

案例

事件排程中心
// 事件中心,做事件排程
 const fs = require("fs");
 let events = {
   _events: [],
   on(fn) {
     this._events.push(fn);
   },
   emit(data) {
     this._events.forEach((fn) => fn(data));
   },
 };
           
訂閱
let arr = [];
 events.on((data) => {
   // 訂閱
   console.log("讀取");
   arr.push(data);
   if (arr.length === 2) {
     console.log("讀取完畢", arr); // 訂閱完成
   }
 });
           
釋出
fs.readFile("./a.txt", "utf-8", (err, data) => {
   events.emit(data); // 釋出
 });

 fs.readFile("./b.txt", "utf-8", (err, data) => {
   events.emit(data);
 });
           

觀察者模式

  • 基于釋出/訂閱模式
  • 該模式存在兩個角色:觀察者和被觀察者
  • 結合vue了解
  • 在vue2.x 資料雙向綁定中,隻要vue的資料(狀态)變化,依賴該資料的視圖就要更新

案例

被觀察者
class Subject {
  constructor(name) {
    this.name = name;
    this.observers = []; // 存放有哪些對象正在觀察我
    this.state = "state"; // 狀态資料
  }
  attach = (o) => {
    this.observers.push(o); // 訂閱要觀察我的對象
  };
  setState = (newState) => {
    this.state = newState;
    this.observers.forEach((o) => o.update(this.name, newState)); //隻要我狀态發生變化,我就會同步給我給所有觀察我的對象
  };
}
           
觀察者
class Observer {
  constructor(name) {
    this.name = name;
  }
  update = (o, state) => { //接收被觀察者同步過來的狀态
    console.log(this.name + ":" + o + state);
  };
}
           
被觀察者執行個體
有若幹的觀察者
let o1 = new Observer("ob1");
let o2 = new Observer("ob2");
           
建立觀察者和被觀察者之間的關系
s.attach(o1);
s.attach(o2);
           
變更被觀察者狀态

s.setState(“變化了”);

s.setState(“狀态變更了”);

關聯技術

  • vue 資料雙向綁定
  • vuex…