You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.
在前端开发过程中,我们经常会在内存中缓存一些数据,其实javascript的缓存比较简单,只需要声明一个变量或把一些数据挂到某个对象上即可,比如我们要实现一个对所有的ajax请求缓存的方法,简单实现如下:
注意
示例中仅做简单演示,未考虑同时对相同的url请求多次,比如
在上述代码中仍然会发起2次对a的请求,这不是我们讨论的重点,我们重点讨论请求成功并缓存数据后,再请求该url的事情,所以这个问题略过不题
我们回头看一下我们的request方法,会发现这样的问题:
有些url在整个项目中或许只请求一次,我们仍然对它的结果进行缓存,造成资源被白白占用,如果应用在移动端,移动端的内存资源本身就比较宝贵,我们不能浪费
这就要求针对request方法中的缓存做一些改进,使它更智能些。我们需要一种算法,保证缓存的个数不能太多,同时缓存的资源数超多时,它能聪明的删掉那些不常用的缓存数据
那我们看一下,当我们要实现这样一个算法有哪些关键点要考虑:
明确目标后,我们就需要寻找合适的对象来缓存我们的数据:
var obj={}
根据key从obj上查找某个对象,复杂度是O(1),满足我们的第2条要求,但obj上缓存了多少个资源需要我们自已维护
var obj=[]
根据key查找某个对象时,复杂度是O(n),但数组有length,可以自动的帮我们维护当前缓存了多少个资源
我们知道数组是特殊的对象,所以我们可以把数组当成普通的对象来用。
当我们把一个缓存对象push进数组时,再根据缓存对象唯一的key,把它放到这个数组对象上
所以这时候我们第1版本的代码可能类似这样:
使用示例如下:
这时候我们就完成了初步要求,知道缓存个数,查找时复杂度是o(1)
不过我们仍然需要更智能一些的缓存:
我们改造下刚才的代码:
在我们第2版本的代码中,我们添加了最多缓存资源数max,同时每个缓存资源加入了使用频率fre及最后使用时间time,同时我们修改了set方法,考虑了相同key的多次set问题。
我们简单测试下:
接下来我们要考虑一但缓存资源数超出了我们规定的max时,我们要清理掉不常用的资源。清理时我们根据频率的使用fre标志,fre最小的优先清理,同时相同的fre,我们优先清理time比较小的,这也是time设计的意义所在。
所以第3版我们的代码如下:
OK,到这里我们就完成了想要的缓存,我们结合最开始的request方法来进行实际测试:
根据上述使用,我们发现,一但达到缓存的上限后,带来的问题如下:
这时候我们就需要寻找突破。类比我们经常使用的操作系统的缓存区,我们的缓存是否也可以加入一个缓冲区呢?当整个缓存列表加上缓冲区都满的时候,才清空一次缓存区,不但能解决频繁排序的问题,也能很好的保留接下来程序中可能频繁使用到的缓存资源
来,缓存的第4版:
这时候我们再结合request来测试一下:
至此我们就完成了比较完善的缓存模块
当然,后续我们增加缓存资源的生命期,比如20分钟后清除,也是较容易的,不在这里详解。
Magix的Cache模块比这里稍微再复杂些,不过原理都是一样的。
The text was updated successfully, but these errors were encountered: