前端 实现有时间限制的缓存
首先我们需要创建一个名为TimeLimitedCache的构造函数,然后定义一些方法,如set, get,和count。以下是具体的示例代码:
// 定义 TimeLimitedCache 构造函数
var TimeLimitedCache = function( ) {// 初始化一个空的 cache 对象,用于存储将要缓存的数据this.cache = {};
};// 定义 TimeLimitedCache 的各种方法
TimeLimitedCache.prototype = {// 设置缓存数据set: function(key, value, duration) {// 获取当前时间const now = Date.now();// 将数据和过期时间一起作为一个新对象缓存起来const _value = {value: value, // 需要缓存的数据duration: duration, // 所需缓存的时间(ms)start: now // 数据开始缓存的时间};// 将键值对存入 cache对象this.cache[key] = _value;},// 获取缓存数据get: function(key) {// 获取当前时间const now = Date.now();// 使用key从缓存中取出数据const { start, duration, value } = this.cache[key];// 判断数据是否过期if (now - start <= duration) {// 如果数据没有过期,则返回数据return value;} else {// 如果数据过期了,就从缓存中删除,并返回-1表示数据已失效delete this.cache[key];return -1;}},// 获取当前还未过期的缓存的数量count: function() {let cnt = 0;for (let key in this.cache) {// 如果 get 方法返回的不是-1,说明缓存还未过期if (this.get(key) !== -1) {cnt++;}}// 返回未过期的缓存数量return cnt;}
}
改已存在且未过期的键的值
// 更新缓存数据
update: function(key, newValue, duration) {// 使用 get 方法检查键值是否存在且未过期if (this.get(key) != -1) {// 存在未过期的键,我们增更新它的值this.cache[key].value = newValue;// 更新他的过期时间if (duration !== undefined) {this.cache[key].duration = duration;this.cache[key].start = Date.now();}return true;} else {// 键不存在或者已经过期,我们返回 falsereturn false;}
}
这样你就可以使用 update 方法来更新已经存在的键的值了。如果这个键不存在或者已经过期,update 方法会返回 false,而如果更新成功,它会返回 true。请注意,对于过期的键,我们通常认为它已经不存在,所以在这种情况下,你可能会希望用 set 来重新创建一个新键
设置缓存时自动删除过期的键
可以在 set 方法中添加一个检查并删除过期键的步骤。为了不让这个步骤消耗太多时间,我们可以选择只删除一部分过期的键。
下面的代码表示在每次设置新的缓存之前,都会检查并删除10个过期的键(如果存在的话):
set: function(key, value, duration) {// 在设置新的缓存之前,先删除一些过期的键var expiredKeys = Object.keys(this.cache).filter((key) => this.get(key) === -1);for (var i = 0; i < Math.min(10, expiredKeys.length); i++) {delete this.cache[expiredKeys[i]];}// 然后设置新的缓存const now = Date.now();const _value = {value: value,duration: duration,start: now};this.cache[key] = _value;
}
这个代码会在每次设置新的缓存之前,先找出所有过期的键,然后删除其中的前10个(如果存在的话)。这样,我们就可以保证每次在设置新的缓存时,都能够尽可能地释放一些空间。同时,由于我们只删除了一部分过期的键,所以这个步骤不会消耗太多时间。
获取缓存时返回剩余时间而不是判断是否过期
可以通过修改 get 方法,在返回缓存值的同时返回剩余的有效时间。修改后的 get 方法如下所示:
// 获取缓存数据
get: function(key) {// 获取当前时间const now = Date.now();// 如果键存在if(this.cache.hasOwnProperty(key)){// 计算剩余的有效时间const remainingTime = this.cache[key].duration - (now - this.cache[key].start);// 如果剩余的有效时间大于0,返回数据和剩余时间if (remainingTime > 0) {return { value: this.cache[key].value, remainingTime: remainingTime };} else {// 如果数据过期了,就从缓存中删除,并返回-1表示数据已失效delete this.cache[key];return { value: -1, remainingTime: 0 };}}else {// 如果键不存在,直接返回-1和剩余时间0return { value: -1, remainingTime: 0 };}
}
这个版本的 get 方法返回了一个包含 value 和 remainingTime 的对象。 value 仍然代表键对应的值,而 remainingTime 代表这个值的剩余有效时间(以毫秒为单位)。如果这个键不存在或已过期, value 会被设置为 -1 , remainingTime 会被设置为 0 。
以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!
相关文章:
前端 实现有时间限制的缓存
首先我们需要创建一个名为TimeLimitedCache的构造函数,然后定义一些方法,如set, get,和count。以下是具体的示例代码: // 定义 TimeLimitedCache 构造函数 var TimeLimitedCache function( ) {// 初始化一个空的 cache 对象,用于…...
前端将xlsx转成json
第一种方式,用js方式 1.1先安装插件 万事都离不开插件的支持首先要安装两个插件 1.2. 安装xlsx cnpm install xlsx --save注:这块我用的cnpm,原生的是npm,因为镜像的问题安装了cnpm,至于怎么装网上一搜一大堆 1.3安…...
使用LLaMA-Factory微调大模型
使用LLaMA-Factory微调大模型 github 地址 https://github.com/hiyouga/LLaMA-Factory 搭建环境 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory在 LLaMA-Factory 路径下 创建虚拟环境 conda create -p ./venv python3.10激活环境 c…...
C语言二级指针、指针数组
一、二级指针 指针变量也是变量,是变量就应有地址,那指针变量的地址存放在哪里?存放在二级指针变量。 此时,*ppa pa,**ppa a。 二、指针数组 指针数组,顾名思义就是存放指针的数组。 数组每个元素为int类…...
python方法
目录 公共方法 1.容器类型之间的转化 2.运算符 3.通用函数 公共方法 1.容器类型之间的转化 # 类型转化 data_str itcast data_list [hadoop, spark, hive, python, hive] data_tupe (hadoop, spark, hive, python, hive) data_set {hadoop, spark, hive, python,…...
0基础学习区块链技术——去中心化
大纲 去验证的中心化验证者如何验证验证者为什么要去传播 去确认的中心化去存储的中心化 “去中心化”是区块链技术的核心。那么我们该如何理解这个概念呢? 我们可以假想在一次现实转账中,有哪些“中心化”的行为: 判断余额是否足够。即判断…...
索引的强大作用和是否创建的索引越多越好
在经常查询字段上创建索引。 在大数据的情况下,在索引上查找可以提交10倍以上甚至1000倍的速度。 实际测试,不在索引上查找用时12秒左右。建立索引,在索引上查找速度提高只耗时1.1秒左右。当然索引也是一把双刃剑,在一个表上创建索…...
批量GBK转UTF-8
大家都有这样的需求,把GBK编码的源代码转换成utf-8编码的源代码。 毕竟现在UTF-8的支持是很好的。 以前一些旧代码是GBK的,尤其是里面的注释,如果不采用UTF-8,在vscode里面可能看着就是乱码。 试了各种工具,最后发现…...
C#WPF数字大屏项目实战08--生产量/良品统计
1、区域划分 生产量/良品统计这部分位于第二列的第二行 2、livechart拆线图 定义折线图,如下: <lvc:CartesianChart> <lvc:CartesianChart.Series> <!--设置Series的类型为 Line 类型, 该类型提供了一些折线图的实现--> <lvc:LineSeries/>…...
22、matlab锯齿波、三角波、方波:rectpuls()函数/sawtooth()函数/square()函数
1、采样的非周期性矩形 语法 语法1:y rectpuls(t) 返回一个以数组 t 中指示的采样时间采样的连续非周期性单位高度矩形脉冲,该矩形脉冲以 t 0 为中心。 语法2:y rectpuls(t,w) 生成一个宽度为 w 的矩形 参数 t:采样时间 w:矩形宽度…...
手机和WINDOWS电脑蓝牙连接后怎样放歌,无法选择媒体音频 蓝牙媒体音频勾选不上
手机和电脑蓝牙连接后怎样放歌 要将手机通过蓝牙连接到电脑并播放音乐,可以按照以下步骤操作: 确保手机和电脑都支持蓝牙功能,并且蓝牙功能已经开启。 在电脑上,打开“设置”> “设备”> “蓝牙和其他设备”。 点击“添…...
MatrixOne→MatrixOS:矩阵起源的创业史即将用“AI Infra”和“AI Platform”书写新章程
在数字化浪潮的推动下,MatrixOne的故事就像一部科技界的创业史诗,它始于一个简单而宏伟的梦想——构建一个能够支撑起新一代数字世界的操作系统。想象一下,在AIGC时代,数据流动如同“血液”,算法运转如同“心跳”&…...
vue3将自定义组件插入指定dom
需求简要描述 页面渲染了一个 id 为 videoPlayerId 的div盒子,代码自定义了一个名为CustomComponent 的组件,现在需要在vue3中,通过纯 js 的方式将组件 CustomComponent 插入 videoPlayerId 的div中,作为其子节点。 实现代码 C…...
flutter封装日历选择器(单日选择)
简单封装: 引入库:table_calendar import package:generated/l10n.dart; import package:jade/utils/JadeColors.dart; import package:jade/utils/Utils.dart; import package:util/easy_loading_util.dart; import package:flutter/material.dart; im…...
SwiftUI调用相机拍照
在 SwiftUI 中实现拍照功能,需要结合 UIViewControllerRepresentable 和 UIImagePickerController 来实现相机功能。下面是一个详细的示例,展示如何使用 SwiftUI 来实现拍照功能: 1. 创建一个 ImagePicker 组件 首先,创建一个 U…...
elasticsearch (dsl)
正排索引 和 倒排索引 正排索引:通过id ,查询content 倒排索引:通过content,查询到符合的 ids eg: 正排索引就是通过《静夜思》,找到整片文章。 倒排索引通过“明月”,找到《静夜思》 《望…...
聊聊大模型微调训练全流程的思考
前言 参考现有的中文医疗模型:MedicalGPT、CareGPT等领域模型的训练流程,结合ChatGPT的训练流程,总结如下: 在预训练阶段,模型会从大量无标注文本数据集中学习领域/通用知识;其次使用{有监督微调}(SFT)优化…...
Python变量符号:深入探索与实用指南
Python变量符号:深入探索与实用指南 在Python编程的世界中,变量符号扮演着至关重要的角色。它们不仅是存储数据的容器,更是构建复杂逻辑和算法的基础。然而,对于初学者来说,Python的变量符号可能会带来一些困惑和挑战…...
实验八 页面置换模拟程序设计
网上找到的程序得到的答案经过手算验证是错的,所以自己实现了一个,具体实现看代码吧,多余的操作已经去掉了。 #include <stdio.h> #include <stdlib.h> #include <stdbool.h>#define VM_PAGE 7 /*假设每个页面可以存放10…...
Spring类加载机制揭秘:深度解析“卸载”阶段
1. 引言 在Spring框架中,类的加载和卸载是一个复杂但至关重要的过程。加载主要涉及将类的字节码加载到JVM中,创建对应的Class对象,并准备使其可用的过程。而卸载,则是指当一个类不再被需要时,将其从JVM中清除…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
