模拟 状态数据管理 监听 以及消息管道通信

 variable.js 代码

// variable.js

import { v4 as uuidv4 } from 'uuid';

// 数据状态管理以及通信管道封装
export default class {
  /**
   * 初始化
   * @param {*} data 
   */
  constructor(data = {}) {
    if (typeof data == 'object' && data.length == 'undefined') {
      // 初始化
      this.data = {
        ...data
      }
    } else {
      this.data = {}
    }

    // 初始化监听器
    this.observer = {}

    // 初始化消息通信
    this.pipeline = {}
  }

  /**
   * 赋值
   * @param {*} key 
   * @param {*} data 
   */
  set(key, data = undefined) {
    if (key) {
      const oldData = this.data[key]
      this.data[key] = data

      this.watchEvent(key, data, oldData)

    } else {
      throw new Error('set "key" 不能为空')
    }
  }

  /**
   * 取值
   * @param {*} key 
   * @returns 
   */
  get(key) {
    if (key && typeof key === 'string') {
      return this.data[key]
    } else {
      throw new Error('get "key" 不能为空 且只能是字符串')
    }
  }

  // 取所有值
  getAll() {
    return this.data
  }

  /**
   * 删除
   * @param {*} key 
   */
  remove(key) {
    if (key && typeof key === 'string') {
      const oldData = this.data[key]
      delete this.data[key]

      this.watchEvent(key, this.data[key], oldData)

    } else {
      throw new Error('remove "key" 不能为空 且只能是字符串')
    }
  }

  // 删除所有
  removeAll() {
    this.data = {}
  }

  /**
   * 触发监听器事件
   * @param {*} key 
   * @param {*} newVal 
   * @param {*} oldVal 
   */
  watchEvent(key, newVal, oldVal) {
    // 触发监听器
    if (this.observer[key]) {
      const eventObject = this.observer[key]
      for (let i in eventObject) {  // 遍历循环
        if (i && eventObject[i]) {
          eventObject[i](newVal, oldVal)
        }
      }
    }
  }

  /**
   * 监听 此函数返回一个唯一id 
   * @param {*} name 监听的数据名称
   * @param {*} callBack 参数 newValue oldValue
   * @returns 
   */
  watch(name, callBack) {
    if (name && typeof name === 'string' && typeof callBack === 'function') {
      const id = uuidv4()

      if (!this.observer[name]) {
        this.observer[name] = {}
      }
      this.observer[name][id] = callBack

      return id
    } else {
      throw new Error('watch "name","callBack" 不能为空 且只能是字符串')
    }
  }

  /**
   * 移除监听器
   * @param {*} name 对应的数据名称
   * @param {} id 如未传则清除所有监听
   */
  removeWatch(name, id) {
    if (name && typeof name === 'string') {
      if (this.observer[name] && this.observer[name]) {
        if (id) {
          this.observer[name][id] = null
          delete this.observer[name][id]
        } else {
          for (let i in this.observer[name]) {  // 遍历循环
            this.observer[name][i] = null
            delete this.observer[name][i]
          }
        }

      } else {
        console.warning('ID:', id, ' 的监听器不存在 可能在此之前已经被移除')
      }
    } else {
      throw new Error('removeWatch "name","id" 不能为空 且只能是字符串')
    }
  }

  /**
   * 创建监听事件 
   * @param {*} name 管道标识
   * @param {*} callBack 参数 data、 send = function
   */
  onMessage(name, callBack) {
    if (name && typeof name === 'string' && typeof callBack === 'function') {
      const id = uuidv4()

      if (!this.pipeline[name]) {
        this.pipeline[name] = {}
      }

      this.pipeline[name][id] = callBack

      return id

    } else {
      throw new Error('onMessage "name" 不能为空 且只能是字符串')
    }
  }

  /**
   * 发送管道消息
   * @param {*} name 管道标识
   * @param {*} data 
   * @param {} callBack 回调函数 = 如果接受人接收到事件 后作业写操作 执行了 send 则此回调函数会接收到回执信息
   */
  sendMessage(name, data, callBack) {
    if (name && typeof name === 'string' && this.pipeline[name]) {
      const eventArr = this.pipeline[name]

      for (let i in eventArr) {  // 遍历循环
        eventArr[i](data, callBack)
      }

    } else {
      throw new Error('sendMessage "name","callBack" 不能为空 且只能是字符串')
    }
  }

  /**
   * 移除通信管道
   * @param {*} name 
   * @param {} id 
   */
  removeMessage(name, id) {
    if (name && typeof name === 'string') {
      if (this.pipeline[name] && this.pipeline[name]) {
        if (id) {
          this.pipeline[name][id] = null
          delete this.pipeline[name][id]
        } else {
          for (let i in this.pipeline[name]) {  // 遍历循环
            this.pipeline[name][i] = null
            delete this.pipeline[name][i]
          }
        }

      } else {
        console.warning('ID:', id, ' 的通信管道不存在 可能在此之前已经被移除')
      }
    } else {
      throw new Error('removeWatch "name","id" 不能为空 且只能是字符串')
    }
  }

}

main.js 代码:

// main.js

// 引入全局数据状态管理文件
import variate from './variable.js'
const variable = new variate()

variable.set('a', '张三')

console.log(variable.get('a'))

const WatchIda = variable.watch('a', (newVal, oldVal) => {
  console.log('a新数据:', newVal, '旧数据:', oldVal)
})

const WatchIdb = variable.watch('a', (newVal, oldVal) => {
  console.log('b新数据:', newVal, '旧数据:', oldVal)
})

variable.remove('a')

variable.removeWatch('a', WatchIdb)

variable.set('a', '李四')

console.log('监听ID:', WatchIda, WatchIdb)

variable.removeWatch('a')

variable.set('a', '监听已经全部移除')


// a
const messageIda = variable.onMessage('123456', (data, send) => {
  console.log('a接收到的消息', data)
  if (send) send('a知道了')
})

// c
const messageIdc = variable.onMessage('123456', (data, send) => {
  console.log('c接收到的消息', data)
  if (send) send('c知道了')
})

console.log('ac', messageIda, messageIdc)

variable.removeMessage('123456', messageIda)

// b
variable.sendMessage('123456', 'b发送', (res) => {
  console.log('返回给我的:', res)
})

variable.removeMessage('123456')

variable.sendMessage('123456', '发送', (res) => {
  console.log('返回给我的:', res)
})


运行效果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值