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:

  • 相关阅读:
    logback配置模板
    mail
    jpa,querydsl
    加密签名
    angular2快速开始
    主从复制
    随笔
    缺货源的小伙伴们 我发现一个超级好的货源供应链 分享给大家
    canal+kafka+logstash+es 架构 logstash的配置
    golang 根据图片url获取图片尺寸
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12633112.html
Copyright © 2011-2022 走看看