化繁为简的IndexedDB

介绍

最近做一个项目需要缓存一些数据,不多说直接上localStorage.setItem,没想到数据太大被限制了。

“setStorage:fail QuotaExceededError: Failed to execute ‘setItem’ on ‘Storage’: Setting the value of ‘87b0ac0beb0984f4d792ae03f7264859’ exceeded the quota.”

了解了一下localStorage容量一般在 5M-10M 左右,用来缓存一些简单的数据基本够用。其实浏览器也提供了大数据量的本地存储,像是 IndexedDB 存储数据大小一般在 250M 以上。容量大了但是使用方式也复杂了,因为我只是简单的使用存储一些缓存数据而已,并没有更深的需求,于是为了让 IndexedDB 的使用更加简单和直观,本文将通过将 IndexedDB 的操作 Promise 化,从而简化前端数据存储的操作。

实现

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
/**
* Promise化 IndexedDB 请求
* @param {IDBRequest} request IndexedDB请求对象
* @returns {Promise}
*/
function promisifyRequest(request) {
return new Promise((resolve, reject) => {
request.oncomplete = request.onsuccess = () => resolve(request.result);
request.onabort = request.onerror = () => reject(request.error);
});
}

/**
* 创建数据库存储
* @param {string} dbName 数据库名称
* @param {string} storeName 存储库名称
* @returns {Function}
*/
function createStore(dbName, storeName) {
const request = indexedDB.open(dbName);
request.onupgradeneeded = () => request.result.createObjectStore(storeName);
const dbPromise = promisifyRequest(request);

return (mode, callback) => dbPromise.then(db =>
callback(db.transaction(storeName, mode).objectStore(storeName))
);
}

/**
* 获取默认存储实例
*/
let defaultStore;
function getDefaultStore() {
return defaultStore || (defaultStore = createStore('uniapp-store', 'default'));
}

/**
* 获取数据
* @param {string} key 键
* @param {Function} customStore 自定义存储实例
* @returns {Promise}
*/
export function get(key, customStore = getDefaultStore()) {
return customStore('readonly', store => promisifyRequest(store.get(key)));
}

/**
* 设置数据
* @param {string} key 键
* @param {any} value 值
* @param {Function} customStore 自定义存储实例
* @returns {Promise}
*/
export function set(key, value, customStore = getDefaultStore()) {
return customStore('readwrite', store => {
store.put(value, key);
return promisifyRequest(store.transaction);
});
}

/**
* 删除数据
* @param {string} key 键
* @param {Function} customStore 自定义存储实例
* @returns {Promise}
*/
export function del(key, customStore = getDefaultStore()) {
return customStore('readwrite', store => {
store.delete(key);
return promisifyRequest(store.transaction);
});
}

/**
* 清空存储
* @param {Function} customStore 自定义存储实例
* @returns {Promise}
*/
export function clear(customStore = getDefaultStore()) {
return customStore('readwrite', store => {
store.clear();
return promisifyRequest(store.transaction);
});
}

使用方式

1
2
3
4
5
6
7
8
9
10
import { get, set, del, clear } from '@/utils/cache';

//获取数据
await get(cacheKey);
//写入数据
await set(cacheKey, item);
//删除数据
await del(cacheKey);
//清空存储
await clear();