An introduction to observer Mode
define
The observer model, also known as the publish-subscribe model. It defines a one-to-many dependency between objects, and all dependent objects are notified when an object’s state changes.
Real example
Nowadays, various live streaming platforms are popular, and most people watch some live streaming at ordinary times. If we have a favorite anchor on a live broadcast platform, but her online time is not very fixed, in order not to miss her live broadcast, we have to glance at the mobile phone from time to time to check whether she is online, which is a waste of time and energy. Therefore, we can use the subscription function of the live broadcast platform to subscribe to an anchor, and when the anchor goes online, we will push a message to all the subscribers. In this way, we can timely know that the anchor has gone online and open the live broadcast without wasting time.
Implementation approach
- Specify a publisher (live streaming platform)
- Add a cached list to the publisher for subscribers or callback functions to execute (all viewers subscribing to a particular anchor)
- When the message is finally published, the publisher iterates through the cached list, triggering the subscriber callback letters it holds
Number (traverse the list and push online reminders one by one)
The core code
Const eventCenter = {// clientList: {}, // Subscribe to add key to identify different anchors function (key, observer) { if (! this.clientList[key]) { this.clientList[key] = []; } // Add the subscriber to the cache list this.clientList[key].push(observer); }, // Publish supports passing different keys to distinguish between different bloggers, as well as passing the extra parameter publish: Function () {let key = [].shift.call(arguments), obs = this.clientList[key]; // Stop publishing if there are no subscribers obs || obs.length === 0) { return false; } // arguments for (var I = 0, ob; ob = obs[i++];) { ob.update.apply(ob, arguments); }}}; Const ob1 = {name: 'look ', update: function (arg) {console.log(' ${this.name} received ${arg}'); }} const ob2 = {name: 'arg ', update: function (arg) {console.log(' ${this.name} received ${arg}'); }} const ob3 = {name: 'arg ', update: function (arg) {console.log(' ${this.name} received ${arg}'); }} // subscribe eventCenter.subscribe('aa', ob1); eventCenter.subscribe('aa', ob2); eventCenter.subscribe('bb', ob3); // publish eventCenter.publish('aa', 'host a'); Eventcenter.publish ('bb', 'host b'); Observer 1 receives the notification that Anchor A is online. Observer 2 receives the notification that anchor A is online. Observer 3 receives the notification that anchor B is onlineCopy the code
The above is a simple example of the observer pattern, and the implementation of some front-end responsive frameworks cannot be separated from the core idea of the observer pattern.
Redux
Redux is the react recommended state management repository. Without further elaboration, here is a minimalist implementation of Redux
let createStore = (reducer) => { let state; Listeners = []; // the clientList stores let listeners = []; let getState = () => state; Let dispath = (action) => {// Modify state state = reducer(state, action); // Execute all listeners. ForEach ((l) => l())} // Subscribe to the same subscribe method as in the previous example. { listeners.push(listener); } dispath(); return { getState, dispath, subscribe } }Copy the code
This is the application of the observer pattern in REdux. Subscribe and Dispatch in createStore’s two core apis correspond to the subscribe and publish methods in observer mode, respectively.
Vue
Vue uses the observer pattern for dependency collection. Uniformly notifies all dependencies of batch updates when listening for data changes. Here is the code to simplify extraction.
export default class Dep { static target: ? Watcher; id: number; subs: Array<Watcher>; Constructor () {this.id = id++ // this.subs = []} // Subscribe addSub (sub: Watcher) { this.subs.push(sub) } removeSub (sub: Watcher) { remove(this.subs, Sub)} Depend () {if (dep.target) {dep.target.adddep (this)}} // Stabilize subscriber list first const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } }Copy the code
The above is my understanding and summary of the observer model. Any deviation is welcome to correct.