美文网首页
1.callback(发布订阅模式、观察者模式)

1.callback(发布订阅模式、观察者模式)

作者: 星星的成长之路 | 来源:发表于2020-10-15 13:11 被阅读0次

    1.前期准备

    node 10.0以上
    安装vscode和以下插件:

    • live server 通过localhost启动浏览器
    • code runner 可以运行部分代码

    2.高阶函数(aop、偏函数、函数柯里化)

    一个函数的参数是函数,或者函数的返回值是函数

    2.1 aop 面向切片编程(装饰器、前端埋点)

    2.2 before方法

    // 装饰器  前端埋点 在ajax 的请求中包装一层自己的逻辑
    // 判断this是谁 就看调用时. 前面是谁this就是谁
    Function.prototype.before = function (callback) {
      let self = this;
      return function () {
        // 这个函数中的this指的是 newFn()前面的this
        callback(); // before 的参数
        console.log(this);
        self.apply(self, arguments);
      };
    };
    function fn(val) {
      console.log('一定的功能' + val);
    }
    let newFn = fn.before(function () {
      console.log('在函数执行前执行');
    });
    newFn('你好');
    
    

    2.3 after方法:

    // lodash debounce throttle
    function after(times, callback) {
      // 满足一个特点就是高阶函数 redux
      return function () {
        // Promise.all
        if (--times === 0) {
          callback();
        }
      };
    }
    
    // 高阶函数
    let newFn = after(2, function () {  
      console.log('after'); 
    });
    newFn();
    newFn();
    

    2.4 并发调用接口,可以用计数器

    • 串行 两个人有关系 上一个人的输出是下一个人的输入
    • 并行 两个人没关系 可以一期执行
    // 并发调用接口  两个ajax  ajax1 => name  ajax2 => age  = name+age
    let fs = require('fs');
    fs.readFile('./name.txt', 'utf-8', function (err, data) {
      if (err) return console.log(err);
      newFn3('name', data);
    });
    fs.readFile('./age.txt', 'utf-8', function (err, data) {
      if (err) return console.log(err);
      newFn3('age', data);
    });
    
    let after = function (times, cb) {
      let res = {};
      return function (key, value) {
        res[key] = value;
        if (--times === 0) {
          cb(res);
        }
      };
    };
    
    //这个方法 会在所有异步执行之后执行
    let newFn3 = after(2, function (res) {
      console.log(res);
    });
    

    3.发布订阅模式

    1. 必须先订阅on,才能发布emit;
    2. 发布和订阅之间有一个媒介this_arr=[],通过媒介进行交互,俩人都不管理,因此可以认为二者是独立的;
    3. 每次调用订阅on时,都会把传进来的方法push到this_arr中;
    4. 每次调用发布emit时,需要让this_arr里的方法都执行一遍;
    5. 订阅就是把方法维护到一个数组里;发布就是数组里的方法依次执行;
    6. 观察者模式包含发布订阅模式
    let fs = require('fs');
    function EventEmitter() {
      this._arr = [];  // [on1, on2 ...]
    }
    EventEmitter.prototype.on = function (cb) {
      this._arr.push(cb);
    };
    EventEmitter.prototype.emit = function () {
      this._arr.forEach((fn) => fn.apply(this, arguments));
    };
    
    fs.readFile('./name.txt', 'utf-8', function (err, data) {
      if (err) return console.log(err);
      e.emit('name', data);
    });
    
    fs.readFile('./age.txt', 'utf-8', function (err, data) {
      if (err) return console.log(err);
      e.emit('age', data);
    });
    
    let e = new EventEmitter();
    let obj = {};
    e.on(function (key, value) {
      obj[key] = value;
      if (Object.keys(obj).length === 2) {
        console.log(obj);
      }
    });
    


    4.观察者模式和发布订阅模式的区别
    基于发布订阅模式,但是发布和订阅,两者之间有关系;
    发布订阅模式,发布和订阅之间没有关系;

    5.观察者模式
    观察者Observer;被观察者Subject

    • 被观察者里面应该存放着所有的观察者
    • 被观察者利用attach来装载观察者
    • 被观察者可以自己更新状态且通知自己的观察者
    • 观察者里面有自己的update方法来接受状态变化
    // 观察者模式  基于发布订阅模式
    // 发布订阅 发布和订阅 两者无关
    // 观察者模式 观察者 和 被观察者
    // 被观察者 应该存放着观察者 我家有个小宝宝 有一个状态
    // 被观察者状态变化 要更新自己身上的所有的观察者
    // 被观察者
    class Subject {
      constructor() {
        this.name = '小宝宝';
        this.state = '开心';
        this.arr = [];
      }
      attach(observer) {
        this.arr.push(observer); // 用来装载观察者
      }
      setState(newState) {
        this.state = newState; // 更新状态值
        this.arr.forEach((observer) => observer.update(newState)); // 通知自己所有的观察者
      }
    }
    
    // 观察者
    class Observer {
      constructor(who) {
        this.who = who;
      }
      update(newState) {
        console.log(this.who + '! 小宝宝' + newState); // 接受新的状态
      }
    }
    
    let subject = new Subject('小宝宝');
    let observer1 = new Observer('爸爸');
    let observer2 = new Observer('妈妈');
    
    subject.attach(observer1); // 注册观察者
    subject.attach(observer2);
    
    subject.setState('哭了'); // 被观察者更改状态
    

    相关文章

      网友评论

          本文标题:1.callback(发布订阅模式、观察者模式)

          本文链接:https://www.haomeiwen.com/subject/auinpktx.html