在业务上现在有一个场景,当发生业务行为变化时,需要对各个模块的行为进行数据收集,数据用途可以用作回顾,也可以是例如监控这样的场景。
说白了这个需求就是需要对各个模块状态变更进行记录,然后再格式化上传到服务端。
解题思路有两种一种是状态监听,第二主动收集。
快速实现利用状态管理和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() |
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
长按识别二维码并关注微信
更方便到期提醒、手机管理