javascript观察者模式介绍观察者模式也称为发布-订阅模式,定义了对象之间一对多的依赖关系。当一个对象发生变化时,可以通知依赖的对象。例如:我们订阅了一个栏目,当栏目有新文章时,它会自动通知所有订阅的人。特点发布订阅一对多优点低耦合,观察者和观察目标都被抽象,易于扩展和复用触发(通信)机制,观察目标通知所有观察者缺点一个观察目标下可能有多个观察或者,当观察目标需要通知所有观察者时,会花费很多时间。如果观察者与观察目标之间存在依赖关系,可能会出现循环调用,进入死循环,导致系统崩溃。观察者模式没有相应的观察机制。读者知道观察目标发生了怎样的变化,但只知道观察目标发生了变化,观察目标可能会发送一些无用的更新。简单例子:A、B、C都关注了某个电台,当电台发布新内容的时候通知A、B、C三人。构思:具体构思中,我们可以知道电台作为发布者,有新的内容,需要将他的最新消息推送给ABC的三个订阅者。那么我们就可以知道电台的发布者需要包含新的更新内容,以及有哪些订阅者订阅了。代码实现:简单代码实现:classRadio{constructor(){this.state=0;this.observers=[];}setState(state){this.state=state;this.notifyingObservers();}addObserver(观察者){this.observers.push(观察者);}notifyingObservers(){conststate=this.state;this.observers.forEach(observer=>{observer.update(state);});}}classPeople{constructor(name){this.name=name;}update(content){console.log(`我是${this.name},我收到了更新,更新内容:${content}`);}}//创建订阅者constpeopleA=newPeople('小A');constpeopleB=newPeople('小B');constpeopleC=newPeople('小C');//添加发布者constradio=newRadio();//订阅radio.addObserver(peopleA);radio.addObserver(peopleB);radio.addObserver(peopleC);//发布者发布radio.setState('10月发布的最热歌曲榜单');radio.setState('11月发布的最新原创歌曲榜单');解读:抽象一个发布者(Radio),有更新内容(setState),添加订阅者(addObserver),触发所有订阅者(notifyingObservers);摘要一个订阅者(People),拥有自己的个人信息(如:姓名),以及收到通知后需要执行的动作(updata);当我们每次开始更新消息时不definingObservers方法触发所有观察者的更新。当然,事实上,我们网站上的每个订阅者都有此更新。当本次更新不满足功能需求时,我们也可以从实例中单独设置订阅者。更新;例如:peopleA.update=function(content){//newcode}以上是一个简单的观察者模式场景扩展网页事件代码案例:click解释:可以理解为函数订阅了$('#btn')事件,当$('#btn')的点击被我们的点击触发时,函数接收到触发信息并自己执行,那么这个函数就是一个观察者(订阅者),$('#的点击事件btn')是观察目标(播音员)。Promise代码示例:functionloadImage(url){returnnewPromise(function(resolve,reject){letimage=document.createElement('img');image.onload=function(){resolve(image);}image.onerror=function(){reject('图片加载失败');}image.src=url;});}constsrc='http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=ad13ee4af0f2b211f0238d0ea3f80054/2e2eb9389b504fc26849383ceedde71190ef6df1.jpg'constimg=loadImage(src);img.then(function(img){console.log('width',redefinition(img}tconsole){.width.)img日志('高度',img.height);});解释:promise的resolve是then的执行者,当promise的状态发生变化时(resolve,状态从“未完成”变为“成功”),将then下面的方法一一执行,那么这些then就可以了说是promise观察者,当promise被resolved时,通知所有的观察者。关于promise内部的观察者模式,可以参考https://github.com/xieranmaya/blog/issues/3。promise.then会将内部函数添加到一个回调数组中,异步执行完成后调用该函数一次。每个.then返回一个新的承诺。js事件触发(自定义事件)代码示例:classEventEmitter(){constructor(){this.events={};}//订阅事件on(type,listener){if(!this.events){this.events=Object.create(null);}if(this.events[type]){this.events[type].push(listener)}else{this.events[type]=[listener];}}//触发执行emit(type,...args){if(this.events[type]){this.events[type].forEach(fn=>fn.call(this,...args));}}//解除绑定off(type,listener){id(this.events[type]){this.events[type]=this.events[type].filter(fn=>{returnfn!==listener;});}}}constmyEmitter=newEventEmitter();myEmitter.on('log',function(){console.log('111111')});myEmitter.emit('log');解读:这个和第一种情况有点类似,我们在jq中看到过这样的页面事件写法:$('id').on('click',function(){//事件代码});这是一个事件触发器,在nodejs中使用了大量的事件触发方法。具体可以去nodejs中的EventEmitter方法去大致了解一下它的机制。同理,我们也可以理解react中的生命周期等mvvm框架,大量使用了观察者模式。都是一一定义钩子。当达到状态时,我会触发相应的钩子并执行相应的代码。总结总之,javascript中观察者模式的使用非常广泛。它的低耦合特性,方便多人开发的复杂项目,可以提高效率,大大提高代码的可维护性。