亲宝软件园·资讯

展开

vue 设计数据采集器 用vue设计一个数据采集器

吴文周 人气:0
想了解用vue设计一个数据采集器的相关内容吗,吴文周在本文为您仔细讲解vue 设计数据采集器的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:vue,数据采集,vue,设计数据采集器,下面大家一起来学习吧。

场景

在业务上现在有一个场景,当发生业务行为变化时,需要对各个模块的行为进行数据收集,数据用途可以用作回顾,也可以是例如监控这样的场景。

核心问题

说白了这个需求就是需要对各个模块状态变更进行记录,然后再格式化上传到服务端。
解题思路有两种一种是状态监听,第二主动收集。

状态监听

状态监听优势

快速实现利用状态管理和wacth的机制很快就知道不同模块的状态变更,然后就可以获取数据,再格式化数据,发送给服务端

状态监听劣势

function useA(){
 wacth(new,old){
  if(start){
    if(new.type =='need')
     const a = {
      a:new.a
     }
     const aa = {
      aa:new.aa
     }
     upload(a)
     upload(aa)
  }
 }
}
// 多处数据散落
function useB(){
 // 重复监听
 wacth(new,old){
 // 全局判断
  if(start){
    // 不同状态判断
    if(new.type =='need')
     const b = {
      b:new.b
     }
     //重复数据格式
     const aa = {
      b:new.aa
     }
     upload(b)
     upload(aa)
  }
 }
}

重构实现思路

依赖收集

/*
 * @Description: 采集公共类
 * @version: 1.0.0
 * @Author: 吴文周
 * @Date: 2021-04-20 19:44:35
 * @LastEditors: 吴文周
 * @LastEditTime: 2021-04-22 15:20:50
 */
/**
 * @name: Dep
 * @msg: 依赖收集对象
 */
class Dep {
  private subs: any = []
  // 添加观察者
  public addSub(sub: any) {
    if (sub && sub.update) {
      this.subs.push(sub)
    }
  }
  // 发送通知
  public notify(content: any) {
    this.subs.forEach((sub: any) => {
      sub.update(content)
    })
  }
}
/**
 * @name: Watcher
 * @msg: 观察者对象
 */
class Watcher {
  private cb!: (arg: any) => void
  constructor(cb: (arg: any) => void) {
    // 回调函数负责更新
    this.cb = cb
  }
  // 当数据发生变化的时候更新
  update(content: any) {
    this.cb(content)
  }
}
/**
 * @name: Channel
 * @msg: 缓存消息管道
 */
class Channel {
  // 管道存储数组
  private queue: any = []
  // 管道大小
  private limitSize = 1
  // 管道名称
  public name: string
  constructor(name: string, limitSize = 1) {
    this.name = name
    // 最小尺寸是1
    limitSize = limitSize >= 1 ? limitSize : 1
    this.limitSize = limitSize
  }
  /**
   * @name: push
   * @msg: 添加的数据
   */
  push(item: any) {
    // 如果超出限制尺寸移除第一个
    if (this.limitSize == this.queue.length) {
      this.queue.shift()
    }
    this.queue.push(item)
  }
  /**
   * @name: getLast
   * @msg: 获取最后添加的数据
   */
  getLast() {
    if (this.queue.length > 0) {
      return this.queue[this.queue.length - 1]
    } else {
      throw new Error('no item return')
    }
  }
  /**
   * @name: getLastIndex
   * @msg: 获取最后倒数的数据
   */
  getLastIndex(index: number) {
    try {
      return this.queue[this.queue.length - index - 1]
    } catch (error) {
      throw new Error('no item return')
    }
  }
  /**
   * @name: isEmpty
   * @msg: 管道是否为空
   */
  isEmpty() {
    return this.queue.length == 0
  }
}
export class Collection {
  // 依赖收集对象
  private dep = new Dep()
  // 各个数据频道分类
  private dataQueue = ['A', 'B', 'C']
  // 频道集合
  private channelMap = new Map()
  // 上传队列
  private MQ!: LiveCollectionMQ
  // 策略模式:数据类型不同对应不同的处理机制
  private strategies = {
    A: () => {
      // 可以在不同的管道中获取相对应的数据进行不同逻辑的处理
    },
    B: () => {

    },
    C: () => {
    },
  } as Record<NotifyType, any>
  constructor() {
    this.init()
  }
  private init() {
    // 初始化watcher
    this.intWatcher()
    // 初始化频道
    this.initChannel()
    // 初始化数据
    this.initData()
    // 初始化队列
    this.initMQ()
  }
  /**
   * @name:intWatcher
   * @msg:初始化监听器
   */
  private intWatcher() {
    this.dep.addSub(
      new Watcher((type: NotifyType) => {
        const handlerBack = this.getHandler(type)
        handlerBack()
      }),
    )
  }
  /**
   * @name: initChannel
   * @msg: 初始化频道
   */
  private initChannel() {
    this.dataQueue.forEach(item => {
      this.channelMap.set(item, new Channel(item, 3))
    })
  }
  /**
   * @name: initData
   * @msg: 初始化频道数据
   * @param {*}
   */
  private initData() {
    
  }
  /**
   * @name: initMQ
   * @msg: 初始化上传队列
   */
  private initMQ() {

  }
  /**
   * @name: getMQ
   * @msg:获取消息队列
   */
  public getMQ() {
    return this.MQ
  }
  /**
   * @name:getChannel
   * @msg:根据频道名称获取频道实例
   * @param {name}频道名称
   */
  private getChannel(name: NotifyType) {
    if (this.channelMap.get(name)) {
      return this.channelMap.get(name)
    } else {
      throw new Error('no channel')
    }
  }
  /**
   * @name:notify
   * @msg:依赖通知方法
   * @param {NotifyType} type
   * @param {any} mes
   */
  public notify(type: NotifyType, mes: any) {
    // 设置管道缓存
    this.setChannel(type, mes)
    // 全局统一判断状态判断是否要分发数据
    if (state.value.type) {
      this.dep.notify(type)
    }
  }
  /**
   * @name: setChannel
   * @msg: 设置频道缓存
   * @param {NotifyType} name
   * @param {any} mes
   */
  private setChannel(name: NotifyType, mes: any) {
    const channel = this.getChannel(name)
    channel.push(mes)
  }
  /**
   * @name:getHandler
   * @msg: 获取
   * @param {NotifyType} name
   */
  private getHandler(name: NotifyType) {
    return this.strategies[name]
  }
  /**
   * @name: getChannelLast
   * @msg: 获取指定管道中的最新的数据
   * @param {NotifyType} name
   * @return {*}
   */
  public getChannelLast(name: NotifyType) {
    try {
      const channel = this.getChannel(name)
      return channel.getLast()
    } catch (error) {
      throw new Error(error)
    }
  }
  /**
   * @name: getChannelLast
   * @msg: 获取指定管道中的倒序数据
   * @param {NotifyType} name
   * @param {number} index
   */
  public getChannelItemByLastIndex(name: NotifyType, index: number) {
    try {
      const channel = this.getChannel(name)
      return channel.getLastIndex(index)
    } catch (error) {
      throw new Error(error)
    }
  }
  /**
   * @name: generateA
   * @msg: 生成A数据方法
   */
  public generateA() {
    
  }
  /**
   * @name: generateB
   * @msg: 生成B数据方法
   */
  public generateB() {
    
  }
  /**
   * @name: generateC
   * @msg: 生成C数据方法
   */
  public generateC() {
    
  }
}

export const CollectionHelper = new Collection()

总结

加载全部内容

相关教程
猜你喜欢
用户评论