Implement a simple data response system

Implement a simple data response system

1. Dep

In fact, this is a container for dependency collection. depend collects dependencies, and notify triggers dependencies.

class Dep{
  constructor() {
    this._subs = [];
  }
  depend() {
    this._subs.push(Dep.target)
  }
  notify() {
    this._subs.forEach(item => {
      item.fn();
    })
  }
}

// Actually, this is the beginning of the love between dep and watcher. // A global property is used in watcher to store watcher
Dep.target = null;

function pushTarget(watch) {
  Dep.target = watch;
}

function popTarget() {
  Dep.target = null;
}

2. Understand obverser

Recursively convert all properties of the data object into accessor properties

// Convert to accessor property function defineReactive (obj, key, val, shallow) {

  // Create a dependency collection container let dep = new Dep();
  let childOb = !shallow && observe(val)

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      if(Dep.target) {
        // Collect dependencies dep.depend();
      }
      return val;
      // ...
    },
    set: function reactiveSetter (newVal) {
      if(newVal === val) return;
      // Continue recursively traversing observe(newVal);
      //Trigger dependency dep.notify();
      // ...
    }
  })
}

class Observer{
  constructor(data) {
    this.walk(data);
  }

  walk(data) {
    const keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
      defineReactive(data, keys[i], data[keys[i]])
    }
  }
}

// Recursively convert all properties of the data object into accessor properties function observe (data) {
  if(Object.prototype.toString.call(data) !== '[object Object]') return;
  new Observer(data);
}

At this point, you can convert all properties of any object into accessors

3. Understand watch and observer

const data = {
  a: 1,
  b: 2
}

//First monitor an object observe(data);

The main function of watcher is to detect a certain attribute and trigger a callback when the attribute changes.

class Watcher{
  /**
  * @params {Function} exp a property expression * @params {Function} fn callback */
  constructor(exp, fn) {
    this.exp = exp;
    this.fn = fn;

    //Save watcher
    // Dep.target = this;
    pushTarget(this);

    // Execute the expression function once first, and in the calling process,
    // Trigger the accessor of data.a, and the get of data.a is executed.
    // Trigger dep.depend() to start collecting dependencies this.exp();

    // Release Dep.target
    popTarget();
  }
}

// new Watcher Such a dependency is collected new Watcher(() => {
  return data.a + data.b;
}, () => {
  console.log('change')
})

4. Trigger Dependency

data.a = 3; // change
data.b = 3; // change

5. Summarize the process

  • Convert all properties of an object into accessors
  • When adding watcher to a property, get function of the property will be triggered. The watcher will be stored in the dep dependency container of the property in the get function.
  • When this property changes, the set method of the property will be triggered. set function will execute all the dependencies stored in dep

This is the end of this article about implementing a simple data response system. For more relevant data response system content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Use of data response system for Vue source code analysis

<<:  Introduction to the use of common Dockerfile commands

>>:  How to control the proportion of Flex child elements on the main axis

Recommend

How to run .sh files in Linux system

There are two ways to run .sh files in Linux syst...

A complete guide to CSS style attributes css() and width() in jQuery

Table of contents 1. Basic use of css(): 1.1 Get ...

CSS3 achieves various border effects

Translucent border Result: Implementation code: &...

JS implements multiple tab switching carousel

Carousel animation can improve the appearance and...

MySQL 5.7.21 Installer Installation Graphic Tutorial under Windows 10

Install MySQL and keep a note. I don’t know if it...

How to find identical files in Linux

As the computer is used, a lot of garbage will be...

Detailed explanation of CocosCreator optimization DrawCall

Table of contents Preface What is DrawCall How do...

Example code for implementing auto-increment sequence in mysql

1. Create a sequence table CREATE TABLE `sequence...

Detailed steps for deploying Microsoft Sql Server with Docker

Table of contents 1 Background 2 Create a contain...

Docker mounts local directories and data volume container operations

1. Docker mounts the local directory Docker can s...

Understanding the Lazy Loading Attribute Pattern in JavaScript

Traditionally, developers create properties in Ja...

MySQL intercepts the sql statement of the string function

1. left(name,4) intercepts the 4 characters on th...

Toolkit: A more powerful front-end framework than Bootstrap

Note: Currently, the more popular front-end frame...

MySQL select, insert, update batch operation statement code examples

In projects, batch operation statements are often...

Detailed explanation of XML syntax

1. Documentation Rules 1. Case sensitive. 2. The a...