preface
Released a subscription model is the observer pattern, so this article will first write a basic case, the observer pattern again on this foundation. Write a publish-subscribe pattern case, and then combined with the characteristics of both analysis of some common practice cases in the front-end development process, to help everybody to learn to understand the basic concepts and the difference between the two.
Note that both have something in common: a one-to-many mentality
Subscriber observer
- subscriberAlso known as
Topic Events
, is essentially an object that is used for savingObserver (subscriber)
The carrier, at the same timeAdd observers and notify all observers
For exampleThe company anIs aThe theme events
theThe theme events
Include information about the company’s members, where they are, what they need to do, etc - The observerAlso known as
The subscriber
, usually an object (can also be a function)
For convenience, this article refers to both as subscribers and observers
Observer model
We design an observer pattern: create a subscriber clickDep identified by Click, and then create two watch subscriptions to Click. The subscriber clickDep issues notifications, and the Watch fires collectively
// Construct the subscriber class
class Dep{
constructor(id){
this.id = id; // Subscriber identity
this.subs = []
}
push(watch){
watch.bind_id = this.id; // The subscriber to which the observer belongs
this.subs.push(watch)
}
notify(){
this.subs.forEach((watch) = >{
watch.update()
})
}
}
// Construct the observer class
class Watch{
constructor(update){
this.update = update
}
}
// Create a subscriber instance click dep
var clickDep = new Dep('click');
// Create an observer instance
var w1 = new Watch(() = >console.log('click watch 1'))
var w2 = new Watch(() = >console.log('click watch 2'))
// Add an observer
clickDep.push(w1)
clickDep.push(w2)
// Publish the message
clickDep.notify()
Copy the code
Publish and subscribe model
Create a scheduling center (event center) called Common to manage subscribers and observers, as well as add observer methods and publish subscriber notifications
class Common{
constructor(id){
this.id = id
this.deps = {} // Used to save subscribers
}
createDep(key){
this.deps[key] = []
}
createWatch(update){
return {
bind_id:null,
update
}
}
push(key,watch){
watch.bind_id = key
this.deps[key].push(watch)
}
notify(key){
this.deps[key].forEach((watch) = >{
watch.update()
})
}
}
// Create a scheduling center
const common = new Common('my common')
// Create a subscriber
common.createDep('click')
// Create an observer
var w1 = common.createWatch(() = >console.log('click watch 1'))
var w2 = common.createWatch(() = >console.log('click watch 2'))
// Add an observer
common.push('click',w1)
common.push('click',w2)
// Issue a notification
common.notify('click')
Copy the code
The difference between the two models
From the above example, we can see that the subscriber of the observer mode is independent of each other. In plain English, we create two subscriber instances, clickDep and touchDep, which are located in separate locations and are not managed by a unified object
The publishave-subscribe pattern solves this problem by creating a common object that manages subscribers and the observers they map to, as well as adding observers and publishing subscriber notifications
Application Case Analysis
-
DOM2 event binding: Bind the document with addEventListener to 3 event handlers. Click the page and trigger these three functions collectively
document.addEventListener('click'.() = >{console.log('click handler 1')}) document.addEventListener('click'.() = >{console.log('click handler 2')}) document.addEventListener('click'.() = >{console.log('click handler 3')}) Copy the code
Case Study:
subscriber
: js internal aboutClick event handler collector
The observer
Three:Event handler
news
: click the trigger
-
Promise: Make a simple Promise
class Promise2{ constructor(fn) { this.thenDep = []; // thenDep subscriber this.catchDep = []; fn( this.resolve.bind(this), this.reject.bind(this))}then(cb) { //thenDep adds subscriber CB this.thenDep.push(cb); return this; // return itself to make the chain call } catch(cb) { this.catchDep.push(cb); return this; } resolve(res) { // thenDep releases a message this.thenDep.forEach((cb) = > { cb(res) }) } reject(res) { this.catchDep.forEach((cb) = > { cb(res) }) } } new Promise2(function (resolve, reject) { console.log('handler') setTimeout(function () { resolve({ data: 'resolve message'})},2000) }) .then((res) = > { console.log('then 1', res) }) .then((res) = > { console.log('then 2', res) }) .catch((error) = > { console.log('catch 1', error) }) .catch((error) = > { console.log('catch 2', error) }) Copy the code
Case Study:
-
Subscriber: the [then/ Catch]Dep maintained internally by Promise2
-
Observer: Uses callbacks passed in by then and catch
-
Publish messages: Resolve and Reject are triggered
-
-
Vue template update Subscription: Declare username in vue component data, render with username in three places (e.g. text, HTML, attr), when
<template> <dl> <dt>{{username}}</dt> <dd v-html="username" :data-username="username"></dd> <dd> <button @click="username = 'Jeck'">change username</button> </dd> </dl> </template> <script> export default { data() { return { username:'Tom' // Vue creates a subscriber based on this attribute: [username]Dep}; },... }</script> Copy the code
Case Study:
-
Subscriber: Creates [username]Dep objects inside vue
-
Observer: Three dom renders corresponding to the Update function [text/ HTML /attr]Update
-
Publish message: Username is changed
-
Understand Vue through design patterns
-
Subscriber creation stage: VUE source code, by binding each attribute of data (Object.defineProperty), at the same time create the subscriber [key]Dep of each attribute, through the set function of attribute binding, trigger the subscriber ([key]Dep) notification
-
The observer binding phase occurs when the template template is initially rendered. Vue binds the template update function to the attribute’s subscriber ([key] DEP) as an observer.
-
- {{username}}
{{username}}
-
[username]Dep will publish the message, and the observer textUpdate will be triggered.
Template update function: a function wrapped based on the native JS DOM API, such as passing arguments to node nodes and value targets, performs the following operations
- Attribute update el.setAttribute
- Text updates el.textContent
- HTML update el. InnerHTML
- Input to update the input value
- The class update el. ClassList [add/remove]
- Update el style. Style [name]
The content is summarized according to personal learning experience and notes. There may be some differences in understanding of knowledge points. I hope you can give me more advice and suggestions. Thank you ~ for your second post, please give me a thumbs up if you get anything, thank you ~