减少重复的请求之promise缓存池(构造器版) —— 缓存promise,多次promise等待并返回第一个promise的结果

news2024/9/30 7:24:39

减少重复的请求之promise缓存池 —— 缓存promise,多次promise等待并返回第一个promise的结果

背景简介
当一个业务组件初始化调用了接口,统一个页面多吃使用同一个组件,将会请求大量重复的接口

如果将promise当作一个普通的对象,进行缓存

/**
 * 数据缓存池
 * @param key 唯一标识
 * @param obj 被缓存的对象
 */
function CachedObj() {
  this.cacheMap = new Map(); //? 缓存池
  
  this.get = (key, obj?) => { //* 获取某一个promise的数据(第一次执行设置,第二次执行获取)
    if (!this.cacheMap.has(key) && obj) {
      this.set(key, obj)
    }
    return this.cacheMap.get(key);
  }
  this.set = (key, obj) => { //* 设置某一个promise的数据
    this.cacheMap.set(key, obj);
  }
  this.delete = (key) => { //* 删除某一个promise的数据
    this.cacheMap.delete(key)
  }
  this.clear = () => { //* 清空重置所有的数据
    this.cacheMap.clear()
  }
}
const cachedObjInstance = new CachedObj()

此时会发现,依旧会多次执行相同的promise(调用多个相同的接口),所以
promise的缓存,难点是如何将一旦新建就会立即执行的promise缓存

那如何让promise步立即执行,我想到了函数,第一个设置并缓存promise时,执行promise

公共的地方设置异步缓存池的构造器以及公共的构造器实例

/**
 * 异步缓存池
 * @param promise 被缓存的异步
 * @param key 唯一标识
 * @returns 同一个异步
 */
function CachedPromise() {
  this.cacheMap = new Map(); //? 缓存池
  
  this.get = (key, promiseFn?) => { //* 获取某一个promise的数据(第一次执行设置,第二次执行获取)
    if (!this.cacheMap.has(key) && promiseFn) {
      this.set(key, promiseFn())
    }
    return this.cacheMap.get(key);
  }
  this.set = (key, promise) => { //* 设置某一个promise的数据
    this.cacheMap.set(key, promise);
  }
  this.delete = (key) => { //* 删除某一个promise的数据
    this.cacheMap.delete(key)
  }
  this.clear = () => { //* 清空重置所有的数据
    this.cacheMap.clear()
  }
}
const cachedPromiseInstance = new CachedPromise()

业务内使用

//todo 设置个性化待办的信息
const getWaitCustomizeInfo = async () => {
  if (AppModule.waitCustomizeInfo) { //* 单例模式,存在则不再请求接口
    return await AppModule.waitCustomizeInfo
  }
  const defaultCustomizeInfo = {
    waitPermission: 'personal', //? 默认”只看自己“
  }
  try {
    const res = await cachedPromise.get('globalWaitCustomizeInfo', () => system.userMenuPersonal.userMenuPersonalDetail.request({ menuCode: 'globalWaitCustomizeInfo' }))
    if (res.data) {
      const personalMenus = res.data
      const savedInfo = personalMenus.menuPersonalValue ? JSON.parse(personalMenus.menuPersonalValue).headerValue : defaultCustomizeInfo
      const waitCustomizeInfo = { id: personalMenus.id, ...savedInfo }
      AppModule.setWaitCustomizeInfo(waitCustomizeInfo)
      return waitCustomizeInfo
    }
    AppModule.setWaitCustomizeInfo(defaultCustomizeInfo)
    return defaultCustomizeInfo;
  } catch (error) {
    AppModule.setWaitCustomizeInfo(defaultCustomizeInfo)
    return defaultCustomizeInfo;
  }
}

完美解决!!!

当缓存中的异步完成后,还继续执行下一个异步时,可以改造一下,使用isFulfilled或者then来判断,异步是否完成

/**
 * 异步缓存池
 * @param continueWhenFinished 当缓存中的异步完成后,继续执行下一个异步
 * @param key 唯一标识
 * @param promise 被缓存的异步
 * @param promiseFn 返回需要缓存异步的函数
 */
function CachedPromise(continueWhenFinished = false) {
  this.cacheMap = new Map(); //? 缓存池

  this.get = (key, promiseFn?) => { //* 获取某一个promise的数据(第一次执行设置,第二次执行获取)
    if (this.cacheMap.has(key)) { //* 已有缓存时
      // if (this.cacheMap.get(key).isFulfilled() && promiseFn) { //* 已有缓存,continueWhenFinished 为true,且缓存中的异步已经完成时,执行新的异步并缓存
      if (continueWhenFinished && typeof this.cacheMap.get(key).then !== 'function' && promiseFn) { //* 已有缓存,continueWhenFinished 为true,且缓存中的异步已经完成时,执行新的异步并缓存
        this.set(key, promiseFn())
      }
    }
    if (!this.cacheMap.has(key) && promiseFn) { //* 没有缓存数据时,进行设置
      this.set(key, promiseFn())
    }
    return this.cacheMap.get(key);
  }
  this.set = (key, promise) => { //* 设置某一个promise的数据
    this.cacheMap.set(key, promise);
  }
  this.delete = (key) => { //* 删除某一个promise的数据
    this.cacheMap.delete(key)
  }
  this.clear = () => { //* 清空重置所有的数据
    this.cacheMap.clear()
  }
}
const cachedPromiseInstance = new CachedPromise()```

注意实现
1、promise一旦新建就会立即执行,所以 要将promise保成函数传入;
2、构造器实例,必须在初始化调用接口的组件外部使用,才能起到缓存promise的作用;放在组件内,每次都会创建一个全新的缓存池
3、记得要处理promise rejected的场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179037.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vulhub weblogic 靶场攻略

一:WebLogic 后台弱⼝令GetShell(weak_password ) 漏洞描述 通过弱⼝令进⼊后台界⾯ , 上传部署war包 , getshell 影响范围 全版本(前提后台存在弱⼝令) 环境搭建 cd vulhub-master/weblogic/weak_password doc…

【STM32开发环境搭建】-4-在STM32CubeMX中新增Keil(MDK-ARM) 5的工程目录(包含指定路径的C和H文件)

案例背景: 由于Keil(MDK-ARM)5工程:DEMO_STM32F030C8T6.uvprojx是由STM32CubeMX工具生成的,如果我们在Keil工程中手动添加了一些c文件和h文件的Include Path包含路径,会在STM32CubeMX下一次生成uvprojx文件时,被删除&…

纯软件小白 学习DDR5

问题 1.你知道当你打开游戏加载存档时候计算机是在做什么吗? 由于你的CPU只有在数据被加载到DRAM的时候才可以工作,所以当你需要用数据的时候,数据会从SSD复制到DRAM这一过程需要时间,所以会有加载(所有3D模型、纹理…

【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】

目录 stm32电路磁编码器电路电机驱动电路电流采样电路电机选择本文示例硬件说明 为了承载和验证本文的FOC代码工程,本节设计了一个简易的三相无刷电机 硬件套件,主控采用非常常用的stm32f103c8t6单片机,电机编码器采用MT6701,电机…

电源的带载能力怎么判断?Namisoft为您介绍测试方法

确保电源在各种负载条件下都能稳定工作,是电源设计者面临的重要挑战。本文将详细介绍如何通过带载测试来评估电源的负载能力。 电源带载测试介绍 带载能力指电源在其规定条件下,所能承受的最大负载能力。电源带载测试就是对电源模块的负载能力进行测试&a…

调试分析:[跳数度量]更改为[距离度量]后的 routing_bellmanford 算法

回顾复习2023年8月的《★修改Exata6.2源码:〔修改Bellmanford最短路径路由的衡量标准从【路由跳数】改为【“路由器节点间的物理距离”】,并动画演示〕》,VS2015调试Exata,跟踪调试修改后的[ routing_bellmanford.cpp ]源码&#…

AgentScope : 与CodeAct智能体对话

参考: 非一般程序猿第六季Agent入门实战篇(三)–CodeActAgent篇 Conversation with CodeAct Agent 0,简介 CodeAct Agent是一个Agent,它不仅可以聊天,还可以为你编写和执行Python代码。在本示例中,将介绍另一种赋予Agent调用工具能力的方法,特别是通过…

Mac 卸载 IDEA 流程

1、现在应用程序中删除Idea 2、进入Library目录 cd /Users/zhengzhaoxiang/Library 3、删除IntelliJIdea2023.3(根据自己的版本而定)记得进去看下是否删除干净了 rm -rf Logs/JetBrains/IntelliJIdea2023.3 rm -rf Preferences/com.jetbrains.intel…

项目学习笔记

Downloads – Oracle VirtualBoxhttps://www.virtualbox.org/wiki/Downloads

启动hadoop集群出现there is no HDFS_NAMENODE_USER defined.Aborting operation

解决方案 在hadoop-env.sh中添加 export HDFS_DATANODE_USERroot export HDFS_NAMENODE_USERroot export HDFS_SECONDARYNAMENODE_USERroot export YARN_RESOURCEMANAGER_USERroot export YARN_NODEMANAGER_USERroot 再次运行即可。

Candance仿真电流镜OTA

1.电路图搭建 图1 上面那层不能直接一横直接连过来,图2只能这样连。但是,图2的M1和M0的电压已经超过了VDD的1.8V。是不行的,需要调整,主要增大M1和M0的宽长比以减小电压。 图2 candance电流镜OTA电路实现 下面这篇文章讲了电流镜…

ROS与无人驾驶学习笔记(一)——ROS基本操作

文章目录 ※ 安装ubuntu 下载 创建虚拟机 安装系统 安装vmware tool 更新源 安装常用软件 ※ 安装ROS 设置软件更新 使用清华源安装 ros测试 认识ROS ROS特点 ROS系统实现 ROS安装 工作需要,转行做码农了。。。 大概是无人驾驶相关的,啥都不会。。。 看成…

JS设计模式之状态模式:优雅地管理应用中产生的不同状态

一. 前言 在过去,我们经常使用条件语句(if-else 语句)来处理应用程序中的不同状态。然而,这种方式往往会让代码变得冗长、难以维护,并可能引入潜在的 bug。而状态模式则提供了一种更加结构化和可扩展的方法来处理状态…

支持超高分辨率图片生成,UltraPixel模型分享

UltraPixel是一种由华为诺亚方舟实验室联合香港科技大学共同开发的超高清图像合成架构,旨在生成具有丰富细节的高质量图像,其分辨率可以从1K一直延伸至6K。 UltraPixel不仅仅是一个图像放大工具,它还能在生成过程中优化细节,提升…

Golang | Leetcode Golang题解之第447题回旋镖的数量

题目: 题解: func numberOfBoomerangs(points [][]int) (ans int) {for _, p : range points {cnt : map[int]int{}for _, q : range points {dis : (p[0]-q[0])*(p[0]-q[0]) (p[1]-q[1])*(p[1]-q[1])cnt[dis]}for _, m : range cnt {ans m * (m - 1)…

Go实现RabbitMQ消息模式

【目标】 go实现RabbitMQ简单模式和work工作模式 go实现RabbitMQ 消息持久化和手动应答 go实现RabbitMQ 发布订阅模式 go使用MQ实现评论后排行榜更新 1. go实现简单模式 编写路由实现生产消息 实现生产消息 MQ消息执行为命令行执行,所以创建命令行执行函数mai…

react-native-Windows配置

一:官网: React Native for Windows macOS Build native Windows & macOS apps with Javascript and React 二:安装依赖 需要以管理员身份运行powershell,然后粘贴下面代码,注意:要安装淘宝镜像,要…

JAVA线程基础二——锁的概述之乐观锁与悲观锁

乐观锁与悲观锁 乐观锁和悲观锁是在数据库中引入的名词,但是在并发包锁里面也引入了类似的思想,所以这里还是有必要讲解下。 悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改,所以在数据被处理前先对数据进行加锁&…

[Redis][典型运用][分布式锁]详细讲解

目录 0.什么是分布式锁1.分布式锁的基础实现2.引入过期时间3.引入校验ID4.引入Lua5.引入Watch Dog(看门狗)6.引入Redlock算法7.其他功能 0.什么是分布式锁 在⼀个分布式的系统中,也会涉及到多个节点访问同⼀个公共资源的情况,此时就需要通过锁来做互斥控…

一拖二快充线:单接与双接的多场景应用

在当代社会,随着智能手机等电子设备的普及,充电问题成为了人们关注的焦点。一拖二快充线作为一种创新的充电解决方案,因其便捷性与高效性而受到广泛关注。本文将深入探讨一拖二快充线的定义、原理以及在单接与双接手机场景下的应用&#xff0…