• Vue3前端实现一个本地消息队列(MQ), 让消息延迟消费或者做缓存


    MQ功能实现的具体代码(TsMQ.ts):

    1. import { v4 as uuidx } from 'uuid';
    2. import emitter from '@/utils/mitt'
    3. // 消息类
    4. class Message {
    5. // 过期时间,0表示马上就消费
    6. exp: number;
    7. // 消费标识,避免重复消费
    8. tag : string;
    9. // 消息体
    10. body : any;
    11. constructor( exp: number , body : any ) {
    12. if (exp == 0) {
    13. this.exp = 0;
    14. }else {
    15. this.exp = Date.now().valueOf() + exp;
    16. }
    17. this.body = body;
    18. this.tag = uuidx();
    19. }
    20. }
    21. export default class TsMQ {
    22. static tsMQ : TsMQ;
    23. cache : boolean;
    24. repository : Map<string, any[]>;
    25. /*
    26. 设置只作为缓存使用
    27. */
    28. setCache(cache : boolean) {
    29. this.cache = cache;
    30. }
    31. /*
    32. 获取单列的MQ对象
    33. */
    34. static getInstance() : TsMQ {
    35. if(this.tsMQ == null) {
    36. this.tsMQ = new TsMQ();
    37. }
    38. return this.tsMQ;
    39. }
    40. constructor() {
    41. this.repository = new Map<string,any[]>();
    42. this.cache = false;
    43. setInterval(()=> {
    44. Array.from(this.repository.keys()).forEach( key => {
    45. let poll = this.repository.get(key) as any[];
    46. if(poll.length > 0) {
    47. poll.forEach( item => {
    48. if (item.exp == 0 || item.exp <= Date.now().valueOf() - 100) {
    49. // 如果是作为缓存使用就不会放入mitt就行推送
    50. if(!this.cache) {
    51. emitter.emit(key,item.body);
    52. }
    53. let single : any[] = this.repository.get(key) as any[];
    54. single = single.filter(dispose => {
    55. return dispose.tag !== item.tag;
    56. });
    57. this.repository.set(key,single);
    58. }
    59. });
    60. }
    61. });
    62. },100)
    63. }
    64. /*
    65. * @describe 放消息入队列
    66. * @param queue : string 队列名称
    67. * @param exp : number 消息消费时间
    68. * @param message : any 消息体
    69. */
    70. pushMessage( queue : string , exp : number, message : any ) {
    71. if(this.repository.has(queue)) {
    72. let single : any[] = this.repository.get(queue) as any[];
    73. single.push(new Message(exp,message));
    74. this.repository.set(queue,single);
    75. }else {
    76. let temp = [];
    77. temp.push(new Message(exp,message));
    78. this.repository.set(queue,temp);
    79. }
    80. }
    81. /*
    82. * @describe 直接获取消息,可以配合做本地缓存,就要去掉constructor的轮询中的事件推送
    83. * @param queue : string 队列名称
    84. */
    85. takeMessage( queue : string ) : any {
    86. let single : any[] = this.repository.get(queue) as any[];
    87. if( single && single.length > 0) {
    88. let message = single.shift();
    89. this.repository.set(queue,single);
    90. return message;
    91. }else {
    92. return '队列没有消息!';
    93. }
    94. }
    95. }
    提示:其中需要用到三方的uuid和mitt,然后要消息持久化可以用到pinia来让消息持久化,本案列没有采用持久化
    uuid的三方包安装命令
    npm install uuid
    mitt的三方安装命令 
    npm install --save mitt 

     其中mitt文件的代码

    1. import mitt from "mitt";
    2. const emitter = mitt();
    3. export default emitter;

    使用方式:

    投送消息
    1. <template>
    2. <div id="app" style="display: flex;flex-direction: column;justify-content: center;height: 100%;width: 100%;margin: 0;padding: 0">
    3. <span @click="pushMQs">MQ投送span>
    4. div>
    5. template>

    提示:这里采用事件模拟投送消息 

     消息订阅代码:
    1. <template>
    2. <div id="app" style="display: flex;flex-direction: column;justify-content: center;height: 100%;width: 100%;margin: 0;padding: 0">
    3. <span @click="takeMQs">MQ获取span>
    4. div>
    5. template>

    效果:

    总结:我们可以看到我们实现了这个功能 ,其中可以用来作为缓存使用,同理可写

  • 相关阅读:
    Shader学习之路——凹凸映射
    [UML]类的关系与类图
    英伟达DeepStream学习笔记47——deepstream sdk安装
    WhatsApp自动营销软件是真实的吗?对做外贸有帮助吗?
    R 语言读写文件
    我的算法笔记 | leetCode easy题感受
    第5章——优化程序性能
    01 - Linux系统概要(再论计算机系统)
    【HTML——旋转火焰】(效果+代码)
    JavaEE 网络原理——TCP的工作机制(末篇 其余TCP特点)
  • 原文地址:https://blog.csdn.net/m0_55337678/article/details/136303946