Source: common/cache-helper.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
 * cache helper
 */
import settings from './settings';
import DataCache from './DataCache';

// 缓存数据对象。为了避免混淆,只缓存至一级结构
const dataCache = new DataCache();

// 获取时间戳
function getTime(t) {
    return t ? t.getTime() : (new Date()).getTime();
}

/**
 * 修正 cacheName
 * @param  {String} cacheName 原始的值,可能是任意格式
 * @return {String}           修正后的 cacheName,以 cachePrefix 开头
 */
function adjustCacheName(cacheName) {
    if (!cacheName) {
        return '';
    }

    cacheName = encodeURIComponent(('' + cacheName).replace(/\//g, '.').replace(/^\./, '').replace(/(^\s+|\s+$)/g, ''));
    if (cacheName.indexOf(settings.cachePrefix)) {
        // cacheName.indexOf(settings.cachePrefix) !== 0 加上前缀
        cacheName = settings.cachePrefix + cacheName;
    }

    return cacheName;
}
/**
 * 根据 cacheType 取得 cacheStorage 对象
 * @param  {String} cacheType
 * @return {Object}
 */
export function getCacheStor(cacheType) {
    let cacheStor = dataCache;

    if (~['sessionStorage', 'localStorage'].indexOf(cacheType)) {
        cacheStor = window[cacheType] || cacheStor;
    }

    return cacheStor;
}
/**
 * 根据 cacheName 名称层级获取对应 dataCache 中的缓存数据
 * @param  {String} cacheName - 名称,以 . 分割层级,如 ups.pa.query.tags.group
 * @param  {String} cacheType - 缓存类型:sessionStorage、localStorage 、 memory(默认)
 * @return {*}                  返回读取到的数据
 */
export function getCacheDataByName(cacheName, cacheType) {
    let data;
    const undefinedVal = void 0;
    const cacheStor = getCacheStor(cacheType);

    if (!(cacheName = adjustCacheName(cacheName))) {
        return data;
    }

    data = cacheStor.getItem(cacheName);
    try {
        data = JSON.parse(data);
    } catch (e) {
        data = data;
    }

    // 缓存的数据设置了有效期 data._e
    if (data && data._e) {
        // console.log(getTime() - data._e, getTime(), data._e);

        if (getTime() - data._e < 0) {
            return data.d;
        }
        // 已过期,数据无效了,移除它
        cacheStor.removeItem(cacheName);

        return undefinedVal;
    }

    return data || undefinedVal;
}
/**
 * 根据 cacheName 名称尝试移除缓存中存在的数据
 * @param  {String|RegExp}  cacheName - 名称,以 . 分割层级,如 ups.pa.query.tags.group。支持正则匹配
 * @param  {String} cacheType - 缓存类型:sessionStorage、localStorage 、 memory(默认)
 * @return {*}
 */
export function deleteCacheDataByName(cacheName, cacheType) {
    const cacheStor = getCacheStor(cacheType);
    let item,
        i,
        len;

    // 为正则,支持模糊删除
    if (cacheName instanceof RegExp) {
        len = cacheStor.length;

        for (i = 0; i < len; i++) {
            item = cacheStor.key(i);

            if (
                !item || // 兼容
                item.indexOf(settings.cachePrefix) !== 0 || // 过滤前缀
                !cacheName.test(item.slice(settings.cachePrefix.length)) // 规则检测
            ) {
                continue;
            }

            // 符合规则,移除
            cacheStor.removeItem(item);
        }

        return;
    }

    // 精确的查找与删除
    if (!(cacheName = adjustCacheName(cacheName))) {
        return;
    }

    cacheStor.removeItem(cacheName);
}
/**
 * 存储数据到本地
 * @param {String} cacheName - 用于存储的名称
 * @param {*}      data - 任意类型的数据
 * @param {String} cacheType - 存储类型,支持三种方式:sessionStorage、localStorage 和内存中(默认)
 */
export function saveTOCache(cacheName, data, cfg = {}) {
    if (!(cacheName = adjustCacheName(cacheName))) {
        return;
    }

    console.log(cacheName, data, cfg);

    const {cache: cacheType, expires} = cfg;
    const cacheStor = getCacheStor(cacheType);

    // expires 应为毫秒整数
    if (+expires) {
        data = {
            d: data,
            _e: (expires instanceof Date) ? getTime(expires) : (getTime() + expires)
        };
    }

    if (cacheStor === dataCache) {
        // 存到内存 dataCache
        cacheStor.setItem(cacheName, data);
    } else {
        cacheStor.setItem(cacheName, JSON.stringify(data));
    }
}

/**
 * 是否为类字符串
 */
export function isString(text) {
    const type = typeof text;

    return 'string' === type || 'number' === type;
}
/**
 * 返回包装done/fail API语法糖的 Promise
 * @param  {Boolean} isJquery 是否为 jQuery,为true 则返回 $.Deferred
 * @return {Promise}
 */
export function getPromise(isJquery) {
    if (isJquery) {
        return $.Deferred();
    }

    let resolve, reject;
    const $p = new window.Promise((rs, rj) => {
        resolve = rs;
        reject = rj;
    });

    $p.resolve = resolve;
    $p.reject = reject;

    $p.done = function (cb) {
        return $p.then(cb);
    };

    $p.fail = function (cb) {
        return $p.then(null, cb);
    };

    $p.always = function (cb) {
        return $p.then(cb, cb);
    };

    return $p;
}