菜?🥬就多练!- 每天思考一个NPM库(每日更新)

129 阅读3分钟

承接上篇文章「看看4.4k🔥stars的chatGPT API仓库干了啥」,其中用到了「map缓存库」map-age-cleaner 和**「promise管理库」p-defer两个库来进行缓存控制和promise管理,今天给大家介绍一下:

p-defer

📦 仓库地址:github.com/sponsors/si…

首先看一下官方示例,我们常用到的defer函数就可以用这个库来实现:

话不多说,直接看源码:

源码其实也很简单,行数非常少,和一般Promise使用方式相对比,主要就做了两件事:

  • 创建一个空对象,统一管理promise本身;
  • 将改变Promise状态(pending => resolve/reject)的方法也放到对象中管理

一些联想到的用法:

  1. 是不是想到了发布订阅模式hhh,改变状态的方法相当于emit了一个事件,只是和发布订阅模式不同的是,这里没有集中管理处理函数,但仍然可以通过then方法注册

  1. 配合回调函数当作一个控制句柄使用
function doSomething(args, cb) => {
	const processingDeferred = pDefer() as DeferredPromise;

	processingDeferred.then(() => {})
  processingDeferred.catch(() => {})

  // 暴露到外部去,由外部控制内部then的执行
  cb(processingDeferred)
}

map-age-cleaner

使Map拥有设置过期时间,自动清除的能力

📦 仓库地址:github.com/SamVerschue…

首先看一下官方示例,我们对map里某个key设置过期时间,1s之后就获取不到了

实现思路:

覆盖map上的set方法,让其在调用原来set方法的同时,对map中所有的key设置过期定时器,到期自动清除即可。

话不多说,直接看源码(经简化):

接着看看set里面做了啥(注释):

最重要的当然是cleanup函数了,里面定义了setupTimer函数,然后for of循环,await处理map里的每个键值对:

最后来看看setupTimer:

看到这里如果感兴趣的小伙伴可以阅读源码,有很多细节和边界条件为方便阅读屏蔽掉了...

一些思考:

  1. 相信有小伙伴发现了,定时器是通过await的方式执行的,相当于线性执行,假如前一个key过期时间比后一个key的过期时间晚怎么办呢,这种情况官方其实也给出了解释:

结论:需要对set里的key进行递增排序,才是合理的,也就是说其实管理一个key是最方便的,多个key就需要自行排序

因为官方是不支持的,假如我们需要实现的话,可以考虑🤔:

  • 创建map时定义一个按过期时间排序的最小堆,时间复杂度O(n),用最小堆是为了更高效率的获取最先过期的key;
  • 在map set的时候去清空所有定时器,再从堆顶开始setupTimer启动定时器

这里就不贴代码了,有更好地实现,小伙伴们可以分享在评论区


🌊总结:

💪持续阅读好的代码库,思考学习好的代码,把自己的成长分享出来。

😊如果有一点点对你学习、工作、思考的帮助,我也会觉得很开心~