最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端JS中sessionStorage,localStorage,IndexedDB本地存儲數(shù)據(jù)的三種方法詳解

 更新時間:2025年10月30日 09:26:29   作者:良山有風來  
這篇文章主要為大家詳細介紹了前端JS中sessionStorage,localStorage,IndexedDB本地存儲數(shù)據(jù)的三種方法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

你是不是也遇到過這樣的場景?

用戶剛填完一個超長的表單,不小心刷新了頁面,所有數(shù)據(jù)都沒了... 從接口請求的數(shù)據(jù),用戶每次操作都要重新加載,體驗卡成PPT... 應用離線狀態(tài)下完全無法使用,用戶直接流失...

別擔心!今天我就帶你徹底解決這些問題??赐赀@篇文章,你將掌握一套完整的數(shù)據(jù)交互方案,讓你的應用在任何網(wǎng)絡狀態(tài)下都能流暢運行。

為什么數(shù)據(jù)存儲這么重要

想象一下,你去超市購物,每次想買什么東西,都要跑回家查一下購物清單,然后再跑回超市... 這得多累?。?/p>

網(wǎng)頁應用也是同樣的道理。合理的數(shù)據(jù)存儲就像你的購物清單,把需要的東西記下來,隨用隨取,效率直接翻倍。

先來看看我們最常用的數(shù)據(jù)獲取方式——Fetch API

Fetch API:現(xiàn)代前端的數(shù)據(jù)搬運工

Fetch API 是現(xiàn)在最主流的數(shù)據(jù)請求方式,比老舊的 XMLHttpRequest 好用太多了。它基于 Promise,寫起來特別優(yōu)雅。

// 最基本的 GET 請求
async function fetchUserData(userId) {
  try {
    // 發(fā)起請求,等待響應
    const response = await fetch(`https://api.example.com/users/${userId}`);
    
    // 檢查響應是否成功(狀態(tài)碼 200-299)
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    // 解析 JSON 數(shù)據(jù)
    const userData = await response.json();
    return userData;
  } catch (error) {
    // 統(tǒng)一的錯誤處理
    console.error('獲取用戶數(shù)據(jù)失敗:', error);
    throw error;
  }
}

// 使用示例
fetchUserData(123)
  .then(user => {
    console.log('用戶信息:', user);
    // 在這里更新頁面顯示
  })
  .catch(error => {
    // 顯示錯誤提示給用戶
    alert('加載用戶信息失敗,請重試');
  });

但光會請求數(shù)據(jù)還不夠,聰明的開發(fā)者都知道:好的數(shù)據(jù)要懂得緩存。這就引出了我們的主角——本地存儲。

本地存儲三劍客:sessionStorage、localStorage、IndexedDB

1. sessionStorage:短暫的記憶

sessionStorage 就像你的短期記憶,頁面會話結束時數(shù)據(jù)就清空了。適合存儲一些臨時數(shù)據(jù)。

// 保存表單草稿
function saveFormDraft(formData) {
  // 將對象轉(zhuǎn)換為 JSON 字符串存儲
  sessionStorage.setItem('formDraft', JSON.stringify(formData));
  console.log('表單草稿已保存');
}

// 讀取表單草稿
function loadFormDraft() {
  const draft = sessionStorage.getItem('formDraft');
  if (draft) {
    // 將 JSON 字符串解析回對象
    return JSON.parse(draft);
  }
  return null;
}

// 清除草稿
function clearFormDraft() {
  sessionStorage.removeItem('formDraft');
  console.log('表單草稿已清除');
}

// 使用示例:頁面加載時恢復草稿
window.addEventListener('load', () => {
  const draft = loadFormDraft();
  if (draft) {
    // 用草稿數(shù)據(jù)填充表單
    document.getElementById('username').value = draft.username || '';
    document.getElementById('email').value = draft.email || '';
    console.log('表單草稿已恢復');
  }
});

// 輸入時實時保存
document.getElementById('myForm').addEventListener('input', (event) => {
  const formData = {
    username: document.getElementById('username').value,
    email: document.getElementById('email').value
  };
  saveFormDraft(formData);
});

2. localStorage:持久的倉庫

localStorage 是長期存儲,除非主動清除,否則數(shù)據(jù)會一直存在。適合存儲用戶偏好設置等。

// 用戶主題偏好管理
class ThemeManager {
  constructor() {
    this.currentTheme = this.getSavedTheme() || 'light';
    this.applyTheme(this.currentTheme);
  }
  
  // 獲取保存的主題
  getSavedTheme() {
    return localStorage.getItem('userTheme');
  }
  
  // 保存主題偏好
  saveTheme(theme) {
    localStorage.setItem('userTheme', theme);
    this.currentTheme = theme;
    console.log(`主題已保存: ${theme}`);
  }
  
  // 應用主題
  applyTheme(theme) {
    document.documentElement.setAttribute('data-theme', theme);
    this.saveTheme(theme);
  }
  
  // 切換主題
  toggleTheme() {
    const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
    this.applyTheme(newTheme);
  }
  
  // 清除主題設置
  clearTheme() {
    localStorage.removeItem('userTheme');
    this.currentTheme = 'light';
    this.applyTheme('light');
    console.log('主題設置已清除');
  }
}

// 使用示例
const themeManager = new ThemeManager();

// 主題切換按鈕
document.getElementById('themeToggle').addEventListener('click', () => {
  themeManager.toggleTheme();
});

3. IndexedDB:大數(shù)據(jù)專家

當你的數(shù)據(jù)量很大,或者需要復雜查詢時,IndexedDB 就是最佳選擇。

// 創(chuàng)建一個簡單的數(shù)據(jù)庫管理器
class DBManager {
  constructor(dbName, version) {
    this.dbName = dbName;
    this.version = version;
    this.db = null;
  }
  
  // 打開數(shù)據(jù)庫
  async open() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, this.version);
      
      request.onerror = () => reject(request.error);
      request.onsuccess = () => {
        this.db = request.result;
        resolve(this.db);
      };
      
      // 第一次創(chuàng)建數(shù)據(jù)庫時初始化結構
      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        
        // 創(chuàng)建用戶表
        if (!db.objectStoreNames.contains('users')) {
          const store = db.createObjectStore('users', { keyPath: 'id' });
          // 創(chuàng)建索引,方便按姓名搜索
          store.createIndex('name', 'name', { unique: false });
        }
        
        // 創(chuàng)建文章表
        if (!db.objectStoreNames.contains('articles')) {
          const store = db.createObjectStore('articles', { keyPath: 'id' });
          store.createIndex('title', 'title', { unique: false });
          store.createIndex('createdAt', 'createdAt', { unique: false });
        }
      };
    });
  }
  
  // 添加數(shù)據(jù)
  async add(storeName, data) {
    const transaction = this.db.transaction([storeName], 'readwrite');
    const store = transaction.objectStore(storeName);
    
    return new Promise((resolve, reject) => {
      const request = store.add(data);
      request.onerror = () => reject(request.error);
      request.onsuccess = () => resolve(request.result);
    });
  }
  
  // 獲取所有數(shù)據(jù)
  async getAll(storeName) {
    const transaction = this.db.transaction([storeName], 'readonly');
    const store = transaction.objectStore(storeName);
    
    return new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onerror = () => reject(request.error);
      request.onsuccess = () => resolve(request.result);
    });
  }
  
  // 按索引查詢
  async getByIndex(storeName, indexName, value) {
    const transaction = this.db.transaction([storeName], 'readonly');
    const store = transaction.objectStore(storeName);
    const index = store.index(indexName);
    
    return new Promise((resolve, reject) => {
      const request = index.getAll(value);
      request.onerror = () => reject(request.error);
      request.onsuccess = () => resolve(request.result);
    });
  }
}

// 使用示例
async function initDB() {
  const dbManager = new DBManager('MyAppDB', 1);
  await dbManager.open();
  
  // 添加示例用戶
  await dbManager.add('users', {
    id: 1,
    name: '張三',
    email: 'zhangsan@example.com',
    createdAt: new Date()
  });
  
  // 獲取所有用戶
  const users = await dbManager.getAll('users');
  console.log('所有用戶:', users);
  
  return dbManager;
}

// 初始化數(shù)據(jù)庫
initDB().then(dbManager => {
  console.log('數(shù)據(jù)庫初始化完成');
});

實戰(zhàn):構建智能數(shù)據(jù)緩存系統(tǒng)

現(xiàn)在讓我們把 Fetch API 和本地存儲結合起來,打造一個真正智能的數(shù)據(jù)緩存系統(tǒng)。

// 智能數(shù)據(jù)管理器
class SmartDataManager {
  constructor() {
    this.cache = new Map(); // 內(nèi)存緩存
  }
  
  // 獲取數(shù)據(jù)(帶緩存)
  async getData(url, options = {}) {
    const {
      cacheKey = url,           // 緩存鍵名
      cacheTime = 5 * 60 * 1000, // 默認緩存5分鐘
      forceRefresh = false      // 強制刷新
    } = options;
    
    // 檢查內(nèi)存緩存
    if (!forceRefresh) {
      const cached = this.getFromCache(cacheKey, cacheTime);
      if (cached) {
        console.log('從內(nèi)存緩存返回數(shù)據(jù)');
        return cached;
      }
      
      // 檢查 localStorage 緩存
      const stored = this.getFromStorage(cacheKey, cacheTime);
      if (stored) {
        console.log('從本地存儲返回數(shù)據(jù)');
        // 同時更新內(nèi)存緩存
        this.cache.set(cacheKey, {
          data: stored,
          timestamp: Date.now()
        });
        return stored;
      }
    }
    
    // 緩存中沒有,從接口獲取
    console.log('從接口獲取數(shù)據(jù)');
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
      
      const data = await response.json();
      
      // 同時更新內(nèi)存緩存和本地存儲
      this.setCache(cacheKey, data);
      this.setStorage(cacheKey, data);
      
      return data;
    } catch (error) {
      console.error('獲取數(shù)據(jù)失敗:', error);
      throw error;
    }
  }
  
  // 從內(nèi)存緩存獲取
  getFromCache(key, cacheTime) {
    const cached = this.cache.get(key);
    if (cached && Date.now() - cached.timestamp < cacheTime) {
      return cached.data;
    }
    return null;
  }
  
  // 從本地存儲獲取
  getFromStorage(key, cacheTime) {
    try {
      const stored = localStorage.getItem(`cache_${key}`);
      if (stored) {
        const { data, timestamp } = JSON.parse(stored);
        if (Date.now() - timestamp < cacheTime) {
          return data;
        } else {
          // 緩存過期,清理
          localStorage.removeItem(`cache_${key}`);
        }
      }
    } catch (error) {
      console.warn('讀取緩存失敗:', error);
    }
    return null;
  }
  
  // 設置內(nèi)存緩存
  setCache(key, data) {
    this.cache.set(key, {
      data,
      timestamp: Date.now()
    });
  }
  
  // 設置本地存儲
  setStorage(key, data) {
    try {
      localStorage.setItem(`cache_${key}`, JSON.stringify({
        data,
        timestamp: Date.now()
      }));
    } catch (error) {
      console.warn('存儲緩存失敗:', error);
      // 如果存儲失?。ū热绯鋈萘浚?,清理最舊的緩存
      this.cleanupStorage();
    }
  }
  
  // 清理過期緩存
  cleanupStorage() {
    const keysToRemove = [];
    
    for (let i = 0; i < localStorage.length; i++) {
      const key = localStorage.key(i);
      if (key.startsWith('cache_')) {
        try {
          const stored = JSON.parse(localStorage.getItem(key));
          // 刪除超過1天的緩存
          if (Date.now() - stored.timestamp > 24 * 60 * 60 * 1000) {
            keysToRemove.push(key);
          }
        } catch (error) {
          // 數(shù)據(jù)格式錯誤,直接刪除
          keysToRemove.push(key);
        }
      }
    }
    
    keysToRemove.forEach(key => localStorage.removeItem(key));
  }
  
  // 清除指定緩存
  clearCache(key) {
    this.cache.delete(key);
    localStorage.removeItem(`cache_${key}`);
  }
  
  // 清除所有緩存
  clearAllCache() {
    this.cache.clear();
    Object.keys(localStorage)
      .filter(key => key.startsWith('cache_'))
      .forEach(key => localStorage.removeItem(key));
  }
}

// 使用示例
const dataManager = new SmartDataManager();

// 獲取用戶列表(帶緩存)
async function loadUsers() {
  try {
    const users = await dataManager.getData('/api/users', {
      cacheKey: 'user_list',
      cacheTime: 10 * 60 * 1000 // 緩存10分鐘
    });
    
    // 渲染用戶列表
    renderUserList(users);
  } catch (error) {
    // 顯示錯誤狀態(tài)
    showError('加載用戶列表失敗');
  }
}

// 強制刷新數(shù)據(jù)
async function refreshUsers() {
  try {
    const users = await dataManager.getData('/api/users', {
      cacheKey: 'user_list',
      forceRefresh: true // 強制從接口獲取最新數(shù)據(jù)
    });
    
    renderUserList(users);
    showSuccess('數(shù)據(jù)已刷新');
  } catch (error) {
    showError('刷新數(shù)據(jù)失敗');
  }
}

離線優(yōu)先:打造極致用戶體驗

現(xiàn)代 Web 應用應該具備離線能力,讓用戶在網(wǎng)絡不穩(wěn)定時也能正常使用。

// 離線優(yōu)先的數(shù)據(jù)同步器
class OfflineFirstSync {
  constructor() {
    this.dbManager = null;
    this.pendingSync = []; // 待同步的操作
    this.init();
  }
  
  async init() {
    // 初始化 IndexedDB
    this.dbManager = new DBManager('OfflineApp', 1);
    await this.dbManager.open();
    
    // 監(jiān)聽網(wǎng)絡狀態(tài)
    this.setupNetworkListener();
    
    // 嘗試同步待處理的操作
    this.trySyncPending();
  }
  
  // 設置網(wǎng)絡狀態(tài)監(jiān)聽
  setupNetworkListener() {
    window.addEventListener('online', () => {
      console.log('網(wǎng)絡已連接,開始同步數(shù)據(jù)...');
      this.trySyncPending();
    });
    
    window.addEventListener('offline', () => {
      console.log('網(wǎng)絡已斷開,進入離線模式');
      this.showOfflineIndicator();
    });
  }
  
  // 創(chuàng)建數(shù)據(jù)(離線優(yōu)先)
  async createData(storeName, data) {
    // 先保存到本地數(shù)據(jù)庫
    const localId = await this.dbManager.add(storeName, {
      ...data,
      _local: true,    // 標記為本地創(chuàng)建
      _synced: false,  // 未同步
      _createdAt: new Date()
    });
    
    // 添加到待同步隊列
    this.pendingSync.push({
      type: 'create',
      storeName,
      data: { ...data, _localId: localId }
    });
    
    // 嘗試立即同步
    await this.trySyncPending();
    
    return localId;
  }
  
  // 嘗試同步待處理操作
  async trySyncPending() {
    if (!navigator.onLine || this.pendingSync.length === 0) {
      return;
    }
    
    console.log(`開始同步 ${this.pendingSync.length} 個操作`);
    
    const successes = [];
    const failures = [];
    
    for (const operation of [...this.pendingSync]) {
      try {
        await this.syncOperation(operation);
        successes.push(operation);
        
        // 從待同步隊列中移除成功的操作
        const index = this.pendingSync.indexOf(operation);
        if (index > -1) {
          this.pendingSync.splice(index, 1);
        }
      } catch (error) {
        console.error('同步操作失敗:', error);
        failures.push(operation);
      }
    }
    
    if (successes.length > 0) {
      console.log(`成功同步 ${successes.length} 個操作`);
      this.showSyncSuccess(successes.length);
    }
    
    if (failures.length > 0) {
      console.warn(`${failures.length} 個操作同步失敗,將在下次重試`);
    }
  }
  
  // 同步單個操作
  async syncOperation(operation) {
    switch (operation.type) {
      case 'create':
        // 調(diào)用 API 創(chuàng)建數(shù)據(jù)
        const response = await fetch('/api/' + operation.storeName, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(operation.data)
        });
        
        if (!response.ok) {
          throw new Error(`創(chuàng)建失敗: ${response.status}`);
        }
        
        const result = await response.json();
        
        // 更新本地數(shù)據(jù),標記為已同步
        // 這里可以根據(jù)需要更新本地記錄的ID等
        console.log('數(shù)據(jù)同步成功:', result);
        break;
        
      default:
        console.warn('未知的操作類型:', operation.type);
    }
  }
  
  // 顯示離線指示器
  showOfflineIndicator() {
    // 在實際應用中,可以顯示一個離線提示條
    const indicator = document.createElement('div');
    indicator.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      background: #ff6b6b;
      color: white;
      text-align: center;
      padding: 10px;
      z-index: 1000;
    `;
    indicator.textContent = '當前處于離線模式,部分功能可能受限';
    indicator.id = 'offline-indicator';
    
    document.body.appendChild(indicator);
  }
  
  // 顯示同步成功提示
  showSyncSuccess(count) {
    const indicator = document.getElementById('offline-indicator');
    if (indicator) {
      indicator.remove();
    }
    
    // 顯示同步成功提示(可以替換為更優(yōu)雅的通知)
    console.log(`成功同步 ${count} 條數(shù)據(jù)`);
  }
  
  // 獲取數(shù)據(jù)(離線優(yōu)先)
  async getData(storeName, useLocalFirst = true) {
    if (useLocalFirst) {
      // 先返回本地數(shù)據(jù)
      const localData = await this.dbManager.getAll(storeName);
      
      // 同時在后臺嘗試獲取最新數(shù)據(jù)
      this.fetchLatestData(storeName);
      
      return localData;
    } else {
      // 直接獲取最新數(shù)據(jù)
      return await this.fetchLatestData(storeName);
    }
  }
  
  // 獲取最新數(shù)據(jù)
  async fetchLatestData(storeName) {
    if (!navigator.onLine) {
      throw new Error('網(wǎng)絡不可用');
    }
    
    try {
      const response = await fetch(`/api/${storeName}`);
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
      
      const data = await response.json();
      
      // 更新本地數(shù)據(jù)庫
      // 這里需要根據(jù)具體業(yè)務邏輯實現(xiàn)數(shù)據(jù)合并
      console.log('獲取到最新數(shù)據(jù):', data);
      
      return data;
    } catch (error) {
      console.error('獲取最新數(shù)據(jù)失敗:', error);
      throw error;
    }
  }
}

// 使用示例
const offlineSync = new OfflineFirstSync();

// 在離線狀態(tài)下創(chuàng)建用戶
async function createUserOffline(userData) {
  try {
    const localId = await offlineSync.createData('users', userData);
    console.log('用戶已創(chuàng)建(本地):', localId);
    showSuccess('用戶已保存,將在網(wǎng)絡恢復后同步');
  } catch (error) {
    console.error('創(chuàng)建用戶失敗:', error);
    showError('保存用戶失敗');
  }
}

性能優(yōu)化與最佳實踐

掌握了基礎用法,再來看看一些提升性能的實用技巧。

// 防抖請求,避免頻繁調(diào)用接口
function createDebouncedFetcher(delay = 500) {
  let timeoutId;
  
  return async function debouncedFetch(url, options) {
    // 清除之前的定時器
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    
    // 設置新的定時器
    return new Promise((resolve, reject) => {
      timeoutId = setTimeout(async () => {
        try {
          const response = await fetch(url, options);
          const data = await response.json();
          resolve(data);
        } catch (error) {
          reject(error);
        }
      }, delay);
    });
  };
}

// 使用防抖的搜索功能
const debouncedSearch = createDebouncedFetcher(300);

document.getElementById('searchInput').addEventListener('input', async (event) => {
  const query = event.target.value.trim();
  
  if (query.length < 2) {
    // 清空搜索結果
    clearSearchResults();
    return;
  }
  
  try {
    const results = await debouncedSearch(`/api/search?q=${encodeURIComponent(query)}`);
    displaySearchResults(results);
  } catch (error) {
    console.error('搜索失敗:', error);
    // 可以顯示本地緩存的結果或錯誤提示
  }
});

// 批量操作優(yōu)化
async function batchOperations(operations, batchSize = 5) {
  const results = [];
  
  for (let i = 0; i < operations.length; i += batchSize) {
    const batch = operations.slice(i, i + batchSize);
    
    // 并行執(zhí)行批次內(nèi)的操作
    const batchResults = await Promise.allSettled(
      batch.map(op => executeOperation(op))
    );
    
    results.push(...batchResults);
    
    // 可選:批次間延遲,避免對服務器造成太大壓力
    if (i + batchSize < operations.length) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }
  
  return results;
}

// 數(shù)據(jù)壓縮,減少存儲空間
function compressData(data) {
  // 簡單的數(shù)據(jù)壓縮示例
  const compressed = {
    // 移除空值
    ...Object.fromEntries(
      Object.entries(data).filter(([_, value]) => 
        value !== null && value !== undefined && value !== ''
      )
    ),
    // 添加壓縮標記
    _compressed: true
  };
  
  return compressed;
}

// 數(shù)據(jù)解壓縮
function decompressData(compressedData) {
  const { _compressed, ...data } = compressedData;
  return data;
}

// 使用壓縮存儲
function saveCompressedData(key, data) {
  const compressed = compressData(data);
  localStorage.setItem(key, JSON.stringify(compressed));
}

function loadCompressedData(key) {
  const stored = localStorage.getItem(key);
  if (stored) {
    const compressed = JSON.parse(stored);
    return decompressData(compressed);
  }
  return null;
}

錯誤處理與監(jiān)控

健壯的應用離不開完善的錯誤處理。

// 增強的錯誤處理包裝器
function createRobustFetcher(options = {}) {
  const {
    maxRetries = 3,
    retryDelay = 1000,
    timeout = 10000
  } = options;
  
  return async function robustFetch(url, fetchOptions = {}) {
    let lastError;
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        // 創(chuàng)建超時控制器
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), timeout);
        
        const response = await fetch(url, {
          ...fetchOptions,
          signal: controller.signal
        });
        
        clearTimeout(timeoutId);
        
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
        
      } catch (error) {
        lastError = error;
        
        console.warn(`請求失敗 (嘗試 ${attempt}/${maxRetries}):`, error);
        
        if (attempt < maxRetries) {
          // 指數(shù)退避延遲
          const delay = retryDelay * Math.pow(2, attempt - 1);
          console.log(`等待 ${delay}ms 后重試...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
      }
    }
    
    // 所有重試都失敗了
    throw new Error(`請求失敗,已重試 ${maxRetries} 次: ${lastError.message}`);
  };
}

// 使用增強的請求器
const robustFetch = createRobustFetcher({
  maxRetries: 3,
  retryDelay: 1000,
  timeout: 15000
});

// 數(shù)據(jù)健康檢查
class DataHealthChecker {
  static checkLocalStorage() {
    const issues = [];
    
    try {
      // 測試寫入和讀取
      const testKey = '__health_check__';
      const testValue = { timestamp: Date.now() };
      
      localStorage.setItem(testKey, JSON.stringify(testValue));
      const retrieved = JSON.parse(localStorage.getItem(testKey));
      localStorage.removeItem(testKey);
      
      if (!retrieved || retrieved.timestamp !== testValue.timestamp) {
        issues.push('localStorage 數(shù)據(jù)完整性檢查失敗');
      }
    } catch (error) {
      issues.push(`localStorage 不可用: ${error.message}`);
    }
    
    return issues;
  }
  
  static checkIndexedDB() {
    return new Promise((resolve) => {
      const issues = [];
      
      const request = indexedDB.open('health_check', 1);
      request.onerror = () => {
        issues.push('IndexedDB 無法打開');
        resolve(issues);
      };
      
      request.onsuccess = () => {
        const db = request.result;
        db.close();
        
        // 清理測試數(shù)據(jù)庫
        indexedDB.deleteDatabase('health_check');
        resolve(issues);
      };
      
      request.onblocked = () => {
        issues.push('IndexedDB 被阻塞');
        resolve(issues);
      };
    });
  }
  
  static async runAllChecks() {
    const localStorageIssues = this.checkLocalStorage();
    const indexedDBIssues = await this.checkIndexedDB();
    
    const allIssues = [...localStorageIssues, ...indexedDBIssues];
    
    if (allIssues.length === 0) {
      console.log('? 所有存儲系統(tǒng)正常');
    } else {
      console.warn('? 存儲系統(tǒng)問題:', allIssues);
    }
    
    return allIssues;
  }
}

// 定期運行健康檢查
setInterval(async () => {
  await DataHealthChecker.runAllChecks();
}, 5 * 60 * 1000); // 每5分鐘檢查一次

總結

通過今天的學習,相信你已經(jīng)掌握了:

  • Fetch API 的現(xiàn)代用法和錯誤處理
  • 三種本地存儲方案的適用場景
  • 如何構建智能緩存系統(tǒng)提升性能
  • 離線優(yōu)先的設計思路
  • 各種性能優(yōu)化和監(jiān)控技巧

數(shù)據(jù)交互不再是簡單的"請求-顯示",而是要考慮緩存、離線、同步、性能等方方面面。一個好的數(shù)據(jù)層設計,能讓你的應用用戶體驗提升好幾個檔次。

以上就是前端JS中sessionStorage,localStorage,IndexedDB本地存儲數(shù)據(jù)的三種方法詳解的詳細內(nèi)容,更多關于JS本地存儲數(shù)據(jù)的資料請關注腳本之家其它相關文章!

相關文章

最新評論

江山市| 屏东县| 北川| 江安县| 凌海市| 胶州市| 乌什县| 阿勒泰市| 巴南区| 荥阳市| 历史| 通化市| 宁晋县| 康马县| 潮安县| 隆子县| 溧阳市| 新源县| 岗巴县| 武宁县| 辽宁省| 新沂市| 师宗县| 尼木县| 阿巴嘎旗| 凤冈县| 昔阳县| 通江县| 双江| 上高县| 开江县| 共和县| 平阳县| 德安县| 永泰县| 醴陵市| 玛多县| 卓尼县| 永新县| 普定县| 鲜城|