观察者模式又称发布-订阅模式
,它定义对象间的一种一对多的依赖关系,当一个对象发生改变的时候,所依赖它的对象都能获得通知。例如:咱们订阅了一个栏目,当栏目有新文章的时候,它会自动通知全部订阅它的人。javascript
代码实现:
简单的代码实现:html
class Radio { constructor() { this.state = 0; this.observers = []; } setState(state) { this.state = state; this.notifyingObservers(); } addObserver(observer) { this.observers.push(observer); } notifyingObservers() { const state = this.state; this.observers.forEach(observer => { observer.update(state); }); } } class People { constructor(name) { this.name = name; } update(content) { console.log(`我是${this.name},我接受到更新了,更新内容:${content}`); } } // 建立订阅者 const peopleA = new People('小A'); const peopleB = new People('小B'); const peopleC = new People('小C'); // 添加发布者 const radio = new Radio(); // 订阅 radio.addObserver(peopleA); radio.addObserver(peopleB); radio.addObserver(peopleC); // 发布者发布 radio.setState('十月份最热歌单发布了'); radio.setState('十一月份最新原创歌单发布了');
Radio
),它有更新内容(setState
)、添加订阅者(addObserver
)、以及触发全部订阅者(notifyingObservers
);People
),他有本身的我的信息(如:name
),以及接受到通知后所须要执行的动做(updata
);notifyingObservers
方法,将全部的observers
的update
都触发了固然,实际上,咱们上的每个订阅者都有这个update,当这个update不知足功能需求的时候,咱们一样能够将实例出来的订阅者单独设置update; 如:java
peopleA.update = function(content) { // 新代码 }
以上就是一个简单的观察者模式的例子node
代码案例:react
<button id="btn">点击</button> <script> $('#btn').click(function() { console.log('btn被点击'); }) </script>
$('#btn')
的click事件,当$('#btn')
的click被咱们点击触发,函数收到触发信息,并自执行。 那么这个函数就是观察者(订阅者),$('#btn')
的click事件就是观察目标(发布者)。代码案例:git
function loadImage(url) { return new Promise(function(resolve, reject) { let image = document.createElement('img'); image.onload = function () { resolve(image); } image.onerror = function () { reject('图片加载失败'); } image.src = url; }); } const src = 'http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=ad13ee4af0f2b211f0238d0ea3f80054/2e2eb9389b504fc26849383ceedde71190ef6df1.jpg' const img = loadImage(src); img.then(function (img) { console.log('width', img.width); return img }).then(function (img) { console.log('height', img.height); });
https://github.com/xieranmaya/blog/issues/3
这篇文档。promise.then会把内部的函数添加到一个callback的数组内,等异步执行完成以后在进行一次调用该函数。每个.then会返回一个新的promise。github
代码案例:数组
class EventEmitter() { 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 => { return fn !== listener; }); } } } const myEmitter = new EventEmitter(); myEmitter.on('log', function() {console.log('111111')}); myEmitter.emit('log');
解读:这个就和第一个案例有点类似,咱们在jq中见过这样的页面事件写法:promise
$('id').on('click', function() { // 事件代码 });
这个就是一种事件触发器,在nodejs里面大量采用了事件触发器的方法。详情能够去看nodejs里面的EventEmitter
方法,就能够大致理解他的机制了。
同理,咱们也能够明白react里面的生命周期等mvvm框架,里面大量采用了观察者模式。它们都是定义了一个个钩子,等状态达到的时候我就触发相对应的钩子,执行相对应的代码。框架
总之,观察者模式在javascript中的使用是很是普遍的。其低耦合的特色方便在多人开发的复杂项目中,能提升效率,使代码的维护性大大提高。