基于vue框架如何实现数据采集器,代码是什么

Admin 2022-10-20 群英技术资讯 329 次浏览

这篇文章主要介绍了“基于vue框架如何实现数据采集器,代码是什么”相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于vue框架如何实现数据采集器,代码是什么文章都会有所收获,下面我们一起来看看吧。

  • 场景

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

核心问题

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

状态监听

状态监听优势

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

状态监听劣势

  • wacth的重复监听,只要使用了wacth,不管是不是你所需要的数据,只要状态变更就会触发改变,监听行为
  • 重复依赖,比如说全局有个开始结束的状态,在使用wacth的时候就需要在不同的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()

总结

  • 我觉得去了解一个框架的一个好的思路就是在运用它的核心原理去解决一个原理,正如之前使用webpack的插件机制一样,这次使用的是vue的依赖收集
  • 状态自治,职责统一是个代码封装的好习惯

感谢各位的阅读,以上就是“基于vue框架如何实现数据采集器,代码是什么”的内容了,经过本文的学习后,相信大家对基于vue框架如何实现数据采集器,代码是什么都有更深刻的体会了吧。这里是群英网络,小编将为大家推送更多相关知识点的文章,欢迎关注! 群英智防CDN,智能加速解决方案
标签: vue数据采集器

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

猜你喜欢

成为群英会员,开启智能安全云计算之旅

立即注册
专业资深工程师驻守
7X24小时快速响应
一站式无忧技术支持
免费备案服务
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
在线客服
微信公众号
返回顶部
返回顶部 返回顶部
在线客服
在线客服