微信小程序全栈开发实践 第三章 微信小程序开发常用的API介绍及使用 -- 3.8 网络接口简介(八)观察者模式介绍及Event模块实现

零、回顾

上节课我们主要学习了EventChannel对象,
这节课我们继续尝试整合用户自动登录,
并着手自定义实现一个观察者模式对象。

一、观察者模式

观察者模式是23个经典设计模式之一,
也是开发中经常使用的设计模式之一,
它的作用是当一个对象被修改的时候,
自动通知依赖它的对象,修改后的状态,
观察者模式,又被称为发布者-订阅者模式。
顾名思义,这个模式既可以订阅又可以发布,
实现该模式的对象,需要有一个方法提供订阅功能,
例如Subscribe、on这样的方法,
通过这个方法知道谁关心这个对象的状态,
还需要一个方法提供发布功能,
例如FireEvent、emit这样的方法,
告诉订阅者有新的状态产生了,。
这个模式最常使用的场景,就是事件派发者对象。
事件派发者对象,允许消费代码监听一个事件,
当这个事件在其他地方被派发的时候,
此处消费代码,将获取一个通知。

在这里插入图片描述

1.lib/event.js

//定义一个类
class Event{
  //容器
  cache; 
  //构造器,new event实例化的时候大概做一个什么事情
  constructor(){
    // this代表的是event的一个实例
    this.cache={}
  }

  /**
   * --订阅
   * on事件:添加一个监听
   * eventType:事件名称
   * func:回调函数
   * 这个事件可能存在多个事件,
   *  一个事件对应多个执行函数
   * 我们可能在多个地方监听一个事件
   */
  on(eventType,func){
    /*
      this.cache[eventType] = func;
      这样的话我们只能监听一个事件了,
      就是你在另外一个地方如果再调用on的话,
      就把前面的给它覆盖掉了
      所以说这个地方我们需要的是把它变成一个,
      我们这个对应的不是直接对应到func,
      对应到一个map上,或者是一个数组。
    */ 
    

    // this.cache[eventType]  如果不存在的话,是第一次的话,它其实等于一个数组。
    ( this.cache[eventType] ||  ( this.cache[eventType] = []) ).push(func);
  }
  /**
   * 移除监听
   * 
   */
  off(eventType,func){
    if(func){
      // 有的话先获取数据
      let stack = this.cache[eventType];
      // 如果拿到这个数组
      if(stack && stack.length > 0){
        // 数组遍历
        for(let j=0;j<stack.length;j++){
          // 直接做移除  索引,删除1个
          if(stack[j] == func){
            stack.splice(j,1)
            break
          } 
        }
      }
    }else{
      // 移除全部
      // 删除一个键值cache这样
      delete this.cache[eventType];
    }
    
  }
  /**
   * 只监听一次
   * on 与 off 的结合
   */
  once(eventType,func){
    // 不能使用箭头函数,只能是用function定义
    function on(){
      // 移除监听
      this.off(eventType,on);
      // 执行func方法
      // 因为用的是function,所以这里可以用一个arguments参数对象,
      // 是实参列表,
      func.apply(this,arguments)
    }


    this.on(eventType,on);


  }
  /**
   * --发布
   * 发布订阅通知
   * 
   */
  emit(eventType,...args){
    const stack = this.cache[eventType];
    // 判断是否存在  && 长度是不是大于1
    if(stack && stack.length > 0 ){
      // 如果是的话,加一个for循环
      stack.forEach(item=>item.apply(this,args))
    }
  } 
}

export default Event;

2.引用和使用Event模块

app.js

import Event from "./lib/event.js"


// getApp()获知App的实例
// getApp().globalEvent  
App({
  ......
  globalEvent:new Event(), //把Event new出来的一个实例,并挂载在App上,
  ......
})

pages/api/index.wxml

<view class="page-section">
  <text class="page-section__title">3.8 Event</text>
  <view class="btn-area">
    <button bindtap="testEvent" type="primary">test event</button>
  </view>
</view>

pages/api/index.js

  //3.8 Event
  testEvent(e){
    const ge = getApp().globalEvent;

    function  func1(a,b){
      console.log("a+b",a+b)
      return a+b
    }

    ge.on("event1",func1);
    ge.emit("event1",1,2);

  },

编译
在这里插入图片描述
pages/api/index.js

  //3.8 Event
  testEvent(e){
    const ge = getApp().globalEvent;

    function  func1(a,b){
      console.log("a+b",a+b)
      return a+b
    }

    ge.once("event1",func1);
    ge.emit("event1",1,2);
    ge.emit("event1",1,2);

  },

编译
在这里插入图片描述
pages/api/index.js

  //3.8 Event
  testEvent(e){
    const ge = getApp().globalEvent;

    function  func1(a,b){
      console.log("a+b",a+b)
      return a+b
    }

    ge.on("event1",func1);
    ge.emit("event1",1,2);
    ge.emit("event1",1,2);

  },

编译
在这里插入图片描述

pages/api/index.js

  //3.8 Event
  testEvent(e){
    const ge = getApp().globalEvent;

    function  func1(a,b){
      console.log("a+b",a+b)
      return a+b
    }

    ge.on("event1",func1);
    ge.emit("event1",1,2);
    ge.off("event1",func1);
    ge.emit("event1",1,2);

  },

编译
在这里插入图片描述
pages/api/index.js

 //3.8 Event
  testEvent(e){
    const ge = getApp().globalEvent;

    function  func1(a,b){
      console.log("a+b",a+b)
      return a+b
    }

    ge.on("event1",func1);
    ge.emit("event1",1,2);
    ge.off("event1");
    ge.emit("event1",1,2);

  },

编译
在这里插入图片描述

有了事件对象,
接下来为了这个模块之间通讯方便,
我们将事件的对象绑定到全局的app对象上,
这样在每个页面里面都可以使用这个事件对象了

二、总结

这节课我们主要介绍了观察者模式,
并据此模式实现了一个event模块。
这个模块在我们接下来的开发中,
将有大大的作用。

下节课我们继续用户登录的自动整合,
尝试在wxp这个模块里面,
扩展出一个request3这样的一个接口。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值