zoukankan      html  css  js  c++  java
  • js 最简单的发布订阅模式

    let _subscriber: any;
    
    function autorun(subscriber: Function) {
      _subscriber = subscriber;
      _subscriber();
      _subscriber = null;
    }
    
    class Observer {
      #list: Function[] = []; // 订阅者
    
      private get _last() {
        if (!this.#list.length) return null;
        return this.#list[this.#list.length - 1];
      }
      // 添加订阅者
      add() {
        if (this._last !== _subscriber) {
          this.#list.push(_subscriber);
        }
      }
    
      // 发布时,把订阅者挨着挨着call
      publish() {
        this.#list.forEach((it: any) => it());
      }
    }
    
    function observable(data: any) {
      const o: Map<string, Observer> = new Map();
      for (const key in data) {
        o.set(key, new Observer());
      }
    
      const proxy = new Proxy(data, {
        get(target: any, key: any) {
          if (_subscriber) o.get(key)!.add();
          return target[key];
        },
        set(target: any, key: any, value: any, receiver: any) {
          if (value === target[key]) return false;
          target[key] = value;
          o.get(key)!.publish();
          return true;
        },
      });
      return proxy;
    }
    
    const obj = observable({ name: "ajanuw", data: "..." });
    
    autorun(() => {
      console.log(obj.name);
      console.log("hello " + obj.name + obj.data);
    });
    
    setTimeout(() => {
      obj.name = "suou";
    }, 1000);
    
    setTimeout(() => {
      obj.data = "......";
    }, 2000);
    

    执行后:

    λ ts-node index.ts
    ajanuw
    hello ajanuw...
    suou
    hello suou...
    suou
    hello suou......
    

    See also:

  • 相关阅读:
    preprocessing
    hist
    RabbitMQ
    线程池
    springmvc功能以及源码实现分析
    西瓜书第二章--模型评估与选择
    西瓜书第一章--绪论
    基于python的递归简述
    python小白学习之旅5
    python小白学习之旅4
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12633112.html
Copyright © 2011-2022 走看看