• 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>

    效果:

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

  • 相关阅读:
    Redis如何实现多可用区?
    QT学习总结之QObject详解
    《机器学习实战》学习笔记(十四)
    FastDeploy UIE 模型 Python 部署示例:GPU、CPU版本安装依赖
    【RocketMQ】消息的高可用与负载均衡
    (第一天:)1.字典赋值默认值、字典解压赋值
    web网页设计期末课程大作业:漫画网站设计——我的英雄(5页)学生个人单页面网页作业 学生网页设计成品 静态HTML网页单页制作
    liunx 磁盘分区格式报错问题及挂载步骤
    【机器学习】集成学习(以随机森林为例)
    三菱PLC若想实现以太网无线通讯,需要具备哪些条件?
  • 原文地址:https://blog.csdn.net/m0_55337678/article/details/136303946