使用indexedDB数据库对接口数据进行前端缓存、定时清除

用法:包裹请求方法即可控制调取缓存还是请求接口,并且判断缓存时间是否超时来进行数据更新

import { fetchWithCache } from '@/utils/indexedDb';

export const getThreeModel = (ciId) =>
  fetchWithCache(
    () => fetchGet(proxyDCIMAPI(`/query?ciId=${ciId}`)),
    `query${ciId}`
  );

工具代码:

/*
 * @Author: Simoon.jia
 * @Date: 2025-03-18 11:00:10
 * @LastEditors: Simoon.jia
 * @LastEditTime: 2025-03-18 17:47:38
 * @Description: 描述
 */
const dbName = 'AppCache';
const dbVersion = 1;

let db;

// 初始化 IndexedDB
function initDB() {
  return new Promise((resolve, reject) => {
    // console.log(db, 'db');

    if (db) {
      resolve(db);
      return;
    }

    const request = indexedDB.open(dbName, dbVersion);

    request.onupgradeneeded = (event) => {
      const db = event.target.result;

      // 创建对象存储
      if (!db.objectStoreNames.contains('apiCache')) {
        db.createObjectStore('apiCache', { keyPath: 'key' });
      }
    };

    request.onsuccess = (event) => {
      db = event.target.result;
      resolve(db);
    };

    request.onerror = (event) => {
      reject(event.target.error);
    };
  });
}

// 通用方法 - 保存数据(缓存时间为1天)
export async function setCache(key, data, ttl = 86400) {
  const database = await initDB();
  const tx = database.transaction('apiCache', 'readwrite');
  const store = tx.objectStore('apiCache');

  const expiry = Date.now() + ttl * 1000; // TTL 单位为秒
  store.put({ key, data, expiry });

  return tx.complete;
}

// 通用方法 - 获取数据
export async function getCache(key) {
  const database = await initDB();
  const tx = database.transaction('apiCache', 'readonly');
  const store = tx.objectStore('apiCache');

  const request = await store.get(key);

  // 将 IndexedDB 请求封装为 Promise
  const result = await new Promise((resolve, reject) => {
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(false);
  });

  if (!result) {
    return null;
  }

  // 检查数据是否过期
  if (result.expiry < Date.now()) {
    await deleteCache(key); // 删除过期数据
    return null;
  }

  return result.data;
}

// 通用方法 - 删除数据
export async function deleteCache(key) {
  const database = await initDB();
  const tx = database.transaction('apiCache', 'readwrite');
  const store = tx.objectStore('apiCache');

  store.delete(key);

  return tx.complete;
}

// 通用方法 - 清空缓存
export async function clearCache() {
  const database = await initDB();
  const tx = database.transaction('apiCache', 'readwrite');
  const store = tx.objectStore('apiCache');

  store.clear();

  return tx.complete;
}

//(缓存时间为1天)
export async function fetchWithCache(fetch, cacheKey = '', ttl = 86400) {
  console.time(`cache-${cacheKey}`);
  // 1. 尝试从缓存中获取数据
  const cachedData = await getCache(cacheKey);
  !!cachedData && console.timeEnd(`cache-${cacheKey}`);
  if (cachedData) {
    // console.log('Cache hit:', cacheKey);
    // console.log(cacheKey);

    return cachedData;
  }

  // 2. 缓存不存在或过期,发起请求
  console.time(`port-${cacheKey}`);
  const data = await fetch();
  console.timeEnd(`port-${cacheKey}`);
  // 3. 保存数据到缓存
  await setCache(cacheKey, data, ttl);

  return data;
}

 

posted @ 2025-03-18 15:14  SimoonJia  阅读(129)  评论(0)    收藏  举报