【10分鐘帶你瞭解釋出訂閱和觀察者模式】

沂蒙趙發表於2019-03-16

【10分鐘帶你瞭解釋出訂閱和觀察者模式】

釋出訂閱模式

--廢話不多說直接上程式碼 釋出和訂閱是沒有關係的他們是靠中介產生關係的,把需要訂閱用的方法先儲存起來,需要的時候再取出來釋出

let fs = require('fs'); // 利用node的API fs模組非同步讀取檔案模擬ajax請求

function EventEmitter(){ this._arr = [];} //定義一個類 也就是釋出和訂閱的媒介

//訂閱: 在EventEmitter建立一個on方法   
EventEmitter.prototype.on = function(callback){ 
    /* callback : on方法執行的時候  就callback儲存到 _arr陣列中  //需要用的時候再取出來執行*/
    this._arr.push(callback); 
}
// 釋出:  釋出時 需要讓on方法中的function依次執行
EventEmitter.prototype.emit = function(){ 
    //emit 執行的時候把 陣列__arr中的方法依次取出來執行
     this._arr.forEach(function(fn){
        fn().applay(this,arguments);  
        /*fn()執行的時候需要將this指向改變一下 然後將emit方法執行傳過來的引數傳過去 on方法中的callback就會接收到*/
    })
}


let e = new EventEmitter();
let zoon = {}

//程式碼執行的時候呼叫on方法 立刻將on中的引數 也就是callback 儲存到this._arr中

e.on(function(){
   console.log('我也執行了');
})
e.on(function(data,key){
    zoo[key] = data;
    if(Object.keys(zoo).length === 2){
    //emit執行了兩次才 執行這哦
        console.log(zoo);
    }
});

//當執行非同步方法的時候 呼叫emit將on中訂閱的方法依次執行
fs.readFile('./name.txt','utf8',function(err,data){ 
    if(err) return console.log(err);
    e.emit(data,'name');
});
fs.readFile('./age.txt','utf8',function(err,data){
    if(err) return console.log(err);
    e.emit(data,'age');
})
複製程式碼

觀察者模式

觀察者模式是基於釋出訂閱模式的

首先有一個 觀察者(屌絲) 和 被觀察者(美女) 屌絲看美女。

class Beauty{ // 美女 (被觀察者)
    constructor(){
        this.state = '生氣';
        this.arr = [];
    }
    attach(observer){ // 將觀察者加入到被觀察者身上
        this.arr.push(observer);
    }
    setState(newState){ // 美女更新自己的狀態
        this.state  = newState;
        this.arr.forEach(observer=>observer.update(newState));
    }
}
// 應該每個資料變化 都應該對應自己的觀察 而不是 一個資料變了 都要更新一下
class Loser{ // 屌絲
    constructor(who){ 
        this.who = who
    }
    // 這個方法是用來被 被觀察者呼叫的
    update(newState){ // 原型上的方法
        console.log(this.who +newState +'了');
    }
}
let subject = new Beauty();
let loser1 = new Loser('屌絲1號');
let loser2 = new Loser('屌絲2號');
subject.attach(loser1); //屌絲1號在看美女
subject.attach(loser2);//屌絲2號也在看美女  此時看美女的有兩個屌絲
subject.setState('開心'); //美女通關setState方法更新自己的狀態  屌絲通過update方法會收到當前美女的狀態 
複製程式碼

相關文章