化繁为简的IndexedDB

61 阅读2分钟

介绍

最近做一个项目需要缓存一些数据,不多说直接上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 化,从而简化前端数据存储的操作。

实现

/**
 * 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);
    });
}

使用方式

import { get, set, del, clear } from '@/utils/cache';

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