--废话很少说直接上代码 发布和订阅是没有关系的他们是靠中介产生关系的,把须要订阅用的方法先存储起来,须要的时候再取出来发布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方法会收到当前美女的状态
复制代码