美文网首页
微信小程序-自己写的一个js监听和发送通知的库

微信小程序-自己写的一个js监听和发送通知的库

作者: 番茄炒西红柿啊 | 来源:发表于2021-11-05 15:02 被阅读0次

    前言

    在iOS开发中,有一个很好用的观察者模式NotificationCenter,能很好的解决一对多,"一"发送通知,"多"接收通知的需求。
    微信小程序中,页面与页面的通讯官方有提供一个叫EventChannel的对象,用法如下:

    wx.navigateTo({
      url: 'test?id=1',
      events: {
        // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
        acceptDataFromOpenedPage: function(data) {
          console.log(data)
        },
        someEvent: function(data) {
          console.log(data)
        }
        ...
      },
      success: function(res) {
        // 通过eventChannel向被打开页面传送数据
        res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
      }
    })
    
    //test.js
    Page({
      onLoad: function(option){
        console.log(option.query)
        const eventChannel = this.getOpenerEventChannel()
        eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
        eventChannel.emit('someEvent', {data: 'test'});
        // 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
        eventChannel.on('acceptDataFromOpenerPage', function(data) {
          console.log(data)
        })
      }
    })
    

    EventChannel能很好的解决上级页面和下级页面的数据交互,但是中间存在跨级或者页面之间不存在跳转层级关系时,EventChannel就办不到了。

    自己动手丰衣足食

    因为开发微信小程序,所以接触了js这门语言。虽然是js小白,但是还是决定根据观察者设计模式来撸一个类似iOS开发中用到的通知库。

    notify.js

    1、引入

    在需要用到的文件中引入

    const notify = require('../../...your file path.../notify');
    
    2. 注册通知方法

    /**

    • 添加通知监听
    • @param {string} name 通知名
    • @param {function} callback 通知回调
    • @return {number} 通知唯一标识, 移除通知时会用到
      */
      addNotify: function(name, callback)

    以注册登录成功的通知为例:

    this.notifyId = notify.addNotify('login_success' , (info)=>{
      // your code
    })
    
    3.移除通知

    /**

    • 移除通知监听
    • @param {string} name 通知名
    • @param {number} index 通知唯一标识,调用addNotify函数时返回的
      */

    removeNotify: function(name, index)

    notify.removeNotify('login_success', this.notifyId)
    
    4.发送通知

    /**

    • 触发通知
    • @param {string} name 通知名
    • @param {any} data 通知时携带的数据
      */

    postNotify: function(name, data={})

    notify.postNotify('login_success',{
      username: '张三',
      age: 18
    })
    

    notify.js 源码如下:

    // 记录通知的对象
    let manager = {}
    
    // manager中的数组是否正在遍历中
    let isForEach = false
    
    // 等待移除通知的队列
    let deleteArr = []
    
    // 自增id
    let notify_id = -1
    
    /**
     * 添加移除通知数据
     * @param {string} name 通知名
     * @param {number} index 对应的标识,详见 add 函数
     */
    function addDeleteNotify(name, index) {
      if (!manager[name]) {return}
      deleteArr.push({name: name, index: index})
    }
    
    /**
     * 移除通知
     * @param {object} obj {name: '通知名', index: '对应标识'}
     */
    function remove(obj) {
      let notify = manager[obj.name]
      if (!notify) {
        return;
      }
      let keyStr = `${obj.index}`
      if (notify[keyStr]) {
        delete notify[keyStr]
      }
      manager[obj.name] = notify
    }
    
    /**
       * 添加通知监听
       * @param {string} name 通知名
       * @param {function} callback 通知回调
       * @return {number} 通知唯一标识, 移除通知时会用到
       */
    function add(name, callback) {
      if (!callback) {
        return -1
      }
      let notify = manager[name] || {}
      notify_id += 1
      notify[`${notify_id}`] = callback
      manager[name] = notify
      return notify_id
    }
    
    /**
     * 初始化方法,其实就是给自己添加一个删除通知的监听
     */
    function init() {
      add('cw_notify_delete', () => {
        deleteArr.forEach(obj => {
          remove(obj)
        })
        deleteArr = []
      })
    }
    
    module.exports = {
      
      /**
       * 添加通知监听
       * @param {string} name 通知名
       * @param {function} callback 通知回调
       * @return {number} 通知唯一标识, 移除通知时会用到
       */
      addNotify: function(name, callback) {
        if (!manager['cw_notify_delete']) {
          // 没有初始化过,初始化一下
          init()
        }
        return add(name, callback)
      },
    
      /**
       * 移除通知监听
       * @param {string} name 通知名
       * @param {number} index 通知唯一标识,调用addNotify函数时返回的
       */
      removeNotify: function(name, index) {
        if (isForEach) {
          // 正在遍历,添加到移除等待队列中
          addDeleteNotify(name, index)
        }else {
          // 未遍历,直接移除
          remove({name: name, index: index})
        }
      },
    
      /**
       * 触发通知
       * @param {string} name 通知名
       * @param {any} data 通知时携带的数据
       */
      postNotify: function(name, data={}) {
        let notify = manager[name]
        if (!notify) {return;}
        isForEach = true
        let func = '', key = ''
        let keys = Object.keys(notify)
        for (let idx in keys) {
          key = keys[idx]; func = notify[key]
          if (Object.prototype.toString.call(func) == '[object Function]') {
            func(data)
          }
        }
        isForEach = false
        if (name != 'cw_notify_delete') {
          this.postNotify('cw_notify_delete')
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:微信小程序-自己写的一个js监听和发送通知的库

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