--廢話很少說直接上代碼 發佈和訂閱是沒有關係的他們是靠中介產生關係的,把須要訂閱用的方法先存儲起來,須要的時候再取出來發佈node
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');
})
複製代碼
觀察者模式是基於發佈訂閱模式的ajax
首先有一個 觀察者(屌絲) 和 被觀察者(美女) 屌絲看美女。數組
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方法會收到當前美女的狀態
複製代碼