CacheFactoryProvider 简介
源码里是这么描述的:
Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to
them.
意思就是通过cacheFactory可以构造一个Cache对象来给予访问和执行权限。
这个Cache对象官方文档是这么说的:
A cache object used to store and retrieve data, primarily used by $http and the script directive to cache templates and other data.
用我自己的话来说就是 提供存储和访问缓存对象的服务,angular内部主要被$http,script指令用于
缓存template和其他数据。我们自己可以在Controller内部使用。
CacheFactoryProvider 用法
1 |
|
看了上面这个一个简单的例子,读者可能会产生如下疑惑:
- 不是名为CacheFactoryProvider吗,怎么在代码里只看到cacheFactory呢?
- cacheFactory是怎么存储对象的?
下面我们来依次解答这两个问题
$cacheFactory的注入
我们首先来看第一个问题,这个问题要牵涉到angular里面的依赖注入机制,我们前面的分析也讲过,
angular会在启动之前通过调用publishExternalAPI
函数先发布一些扩展API,同时定义ng
模块,在定义ng模块的时候就传入了注入provider的方法
1 | angularModule('ng', ['ngLocale'], ['$provide', |
$cacheFactory出现了,它是通过javascript的键值对象作为键传给provider方法。那么它是如何存储
对象的呢?首先我们看它的定义:
CacheFactoryProvider的定义
内部定义了依赖注入核心的$get
方法,$get
方法返回cacheFactory方法(也就是上面实例代码里的
$cacheFactory
参数)。
1 | function $CacheFactoryProvider() { |
CacheFactoryProvider的存储
存储分为这几个核心方法:put
,refresh
,remove
,link
put函数
value会放入data对象中,key会放入lruHash链表1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 put: function(key, value) {
if (isUndefined(value)) return;
//如果设定的capcity小于maxvalue
if (capacity < Number.MAX_VALUE) {
//lruHash 存了当前的key 还有可能是 p 和n (previous和next)
var lruEntry = lruHash[key] || (lruHash[key] = {key: key});
//刷新各节点的次序
refresh(lruEntry);//把当前entry放入链表末尾
}
//如果key 在data里不存在 那么增加size
if (!(key in data)) size++;
data[key] = value;
//当大于capacity时 会清除最早加入的那个
if (size > capacity) {
this.remove(staleEnd.key);//移除淘汰节点stableEnd
}
return value;
}
get函数
Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object
获取存储在cache对象中的指定数据1
2
3
4
5
6
7
8
9
10
11
12get: function(key) {
if (capacity < Number.MAX_VALUE) {
var lruEntry = lruHash[key];
if (!lruEntry) return;
// 获取first的时候 因为staleEnd为first 所以会让staleEnd指向 second
// 内部会执行link 使得 second.p = null
// first.p = third third.n = first
//stableEnd为 second freshEnd为first
refresh(lruEntry);
}
return data[key];
}
remove函数
Removes an entry from the {@link $cacheFactory.Cache Cache} object.
从cache对象删除一个entry
1 | remove: function(key) { |
refresh函数
makes the entry
the freshEnd of the LRU linked list。
把entry 放入链表的末尾1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24function refresh(entry) {
if (entry != freshEnd) {
if (!staleEnd) { //staleEnd为空那么就让他指向当前entry
staleEnd = entry;
} else if (staleEnd == entry) {
//如果淘汰节点等于当前节点
staleEnd = entry.n; //用于把 当前的下一个节点 用作淘汰节点
}
//放入第一个元素时 entry.n,entry.p都为undefined
link(entry.n, entry.p); //当前的上一个节点 和当前的下一个节点
link(entry, freshEnd); // 当前的节点 和 最新的末尾节点
freshEnd = entry;
freshEnd.n = null;
//第一次执行完 结果为: freshEnd = first staleEnd为first
//first.p=null first.n=null
//第二次执行完 结果为:freshEnd = second staleEnd为first
// first.p=null first.n= second
// scecond.p = first scecond.n = null
//第三次执行完 freshEnd = third staleEnd为first first.p=null
//first.n= second
// second.p = first second.n = null
// third.p = second third.n = null
}
}
link函数
bidirectionally(双向链表) links two entries of the LRU linked list
双向链接链表里的两个元素。
1 | function link(nextEntry, prevEntry) { |