彌補localStorage容量缺陷方法詳解
正文
localStorage
是前端本地存儲的一種,其容量一般在 5M-10M
左右,用來緩存一些簡單的數據基本夠用,畢竟定位也不是大數據量的存儲。
在某些場景下 localStorage
的容量就會有點捉襟見肘,其實瀏覽器是有提供大數據量的本地存儲的如 IndexedDB
存儲數據大小一般在 250M
以上。
彌補了localStorage
容量的缺陷,但是使用要比localStorage
復雜一些 mdn IndexedDB
不過已經有大佬造了輪子封裝了一些調用過程使其使用相對簡單,下面我們一起來看一下
localforage
localforage 擁有類似 localStorage
API,它能存儲多種類型的數據如 Array
ArrayBuffer
Blob
Number
Object
String
,而不僅僅是字符串。
這意味著我們可以直接存 對象、數組類型的數據避免了 JSON.stringify
轉換數據的一些問題。
存儲其他數據類型時需要轉換成上邊對應的類型,比如vue3中使用 reactive
定義的數據需要使用toRaw
轉換成原始數據進行保存, ref
則直接保存 xxx.value
數據即可。
安裝
下載最新版本 或使用 npm
bower
進行安裝使用。
# 引入下載的 localforage 即可使用 <script src="localforage.js"></script> <script>console.log('localforage is: ', localforage);</script> # 通過 npm 安裝: npm install localforage # 或通過 bower: bower install localforage
使用
提供了與 localStorage
相同的api,不同的是它是異步的調用返回一個 Promise
對象
localforage.getItem('somekey').then(function(value) { // 當離線倉庫中的值被載入時,此處代碼運行 console.log(value); }).catch(function(err) { // 當出錯時,此處代碼運行 console.log(err); }); // 回調版本: localforage.getItem('somekey', function(err, value) { // 當離線倉庫中的值被載入時,此處代碼運行 console.log(value); });
提供的方法有
getItem
根據數據的 key
獲取數據 差不多返回 null
setItem
根據數據的 key
設置數據(存儲undefined
時getItem獲取會返回 null
)
removeItem
根據key刪除數據
length
獲取key的數量
key
根據 key 的索引獲取其名
keys
獲取數據倉庫中所有的 key。
iterate
迭代數據倉庫中的所有 value/key
鍵值對。
配置
完整配置可查看文檔 這里說個作者覺得有用的
localforage.config({ name: 'My-localStorage' });
設置倉庫的名字,不同的名字代表不同的倉庫,當一個應用需要多個本地倉庫隔離數據的時候就很有用。
const store = localforage.createInstance({ name: "nameHere" }); const otherStore = localforage.createInstance({ name: "otherName" }); // 設置某個數據倉庫 key 的值不會影響到另一個數據倉庫 store.setItem("key", "value"); otherStore.setItem("key", "value2");
同時也支持刪除倉庫
// 調用時,若不傳參,將刪除當前實例的 “數據倉庫” 。 localforage.dropInstance().then(function() { console.log('Dropped the store of the current instance'). }); // 調用時,若參數為一個指定了 name 和 storeName 屬性的對象,會刪除指定的 “數據倉庫”。 localforage.dropInstance({ name: "otherName", storeName: "otherStore" }).then(function() { console.log('Dropped otherStore'). }); // 調用時,若參數為一個僅指定了 name 屬性的對象,將刪除指定的 “數據庫”(及其所有數據倉庫)。 localforage.dropInstance({ name: "otherName" }).then(function() { console.log('Dropped otherName database'). });
idb-keyval
idb-keyval
是用IndexedDB
實現的一個超級簡單的基于 promise
的鍵值存儲。
安裝
npm
npm install idb-keyval
// 全部引入 import idbKeyval from 'idb-keyval'; idbKeyval.set('hello', 'world') .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err)); // 按需引入會搖樹 import { get, set } from 'idb-keyval'; set('hello', 'world') .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err)); get('hello').then((val) => console.log(val));
瀏覽器直接引入 <script src="https://cdn.jsdelivr.net/npm/idb-keyval@6/dist/umd.js"></script>
暴露的全局變量是 idbKeyval
直接使用即可。
提供的方法
由于其沒有中文的官網,會把例子及自己的理解附上
set 設置數據
值可以是 數字、數組、對象、日期、Blobs等,盡管老Edge不支持null。
鍵可以是數字、字符串、日期,(IDB也允許這些值的數組,但IE不支持)。
import { set } from 'idb-keyval'; set('hello', 'world') .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err));
setMany 設置多個數據
一個設置多個值,比一個一個的設置更快
import { set, setMany } from 'idb-keyval'; // 不應該: Promise.all([set(123, 456), set('hello', 'world')]) .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err)); // 這樣做更快: setMany([ [123, 456], ['hello', 'world'], ]) .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err));
get 獲取數據
如果沒有鍵,那么val
將返回undefined
的。
import { get } from 'idb-keyval'; // logs: "world" get('hello').then((val) => console.log(val));
getMany 獲取多個數據
一次獲取多個數據,比一個一個獲取數據更快
import { get, getMany } from 'idb-keyval'; // 不應該: Promise.all([get(123), get('hello')]).then(([firstVal, secondVal]) => console.log(firstVal, secondVal), ); // 這樣做更快: getMany([123, 'hello']).then(([firstVal, secondVal]) => console.log(firstVal, secondVal), );
del 刪除數據
根據 key
刪除數據
import { del } from 'idb-keyval'; del('hello');
delMany 刪除多個數據
一次刪除多個鍵,比一個一個刪除要快
import { del, delMany } from 'idb-keyval'; // 不應該: Promise.all([del(123), del('hello')]) .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err)); // 這樣做更快: delMany([123, 'hello']) .then(() => console.log('It worked!')) .catch((err) => console.log('It failed!', err));
update 排隊更新數據,防止由于異步導致數據更新問題
因為 get
與 set
都是異步的使用他們來更新數據可能會存在問題如:
// Don't do this: import { get, set } from 'idb-keyval'; get('counter').then((val) => set('counter', (val || 0) + 1); ); get('counter').then((val) => set('counter', (val || 0) + 1); );
上述代碼我們期望的是 2
但實際結果是 1
,我們可以在第一個回調執(zhí)行第二次操作。
更好的方法是使用 update
來更新數據
// Instead: import { update } from 'idb-keyval'; update('counter', (val) => (val || 0) + 1); update('counter', (val) => (val || 0) + 1);
將自動排隊更新,所以第一次更新將計數器設置為1
,第二次更新將其設置為2
。
clear 清除所有數據
import { clear } from 'idb-keyval'; clear();
entries 返回 [key, value]
形式的數據
import { entries } from 'idb-keyval'; // logs: [[123, 456], ['hello', 'world']] entries().then((entries) => console.log(entries));
keys 獲取所有數據的 key
import { keys } from 'idb-keyval'; // logs: [123, 'hello'] keys().then((keys) => console.log(keys));
values 獲取所有數據 value
import { values } from 'idb-keyval'; // logs: [456, 'world'] values().then((values) => console.log(values));
createStore 自定義倉庫
文字解釋:表 === store === 商店 一個意思
// 自定義數據庫名稱及表名稱 // 創(chuàng)建一個數據庫: 數據庫名稱為 tang_shi, 表名為 table1 const tang_shi_table1 = idbKeyval.createStore('tang_shi', 'table1') // 向對應倉庫添加數據 idbKeyval.set('add', 'table1 的數據', tang_shi_table1) // 默認創(chuàng)建的倉庫名稱為 keyval-store 表名為 keyval idbKeyval.set('add', '默認的數據')
使用 createStore
創(chuàng)建的數據庫一個庫只會創(chuàng)建一個表即:
// 同一個庫有不可以有兩個表,custom-store-2 不會創(chuàng)建成功: const customStore = createStore('custom-db-name', 'custom-store-name'); const customStore2 = createStore('custom-db-name', 'custom-store-2'); // 不同的庫 有相同的表名 這是可以的: const customStore3 = createStore('db3', 'keyval'); const customStore4 = createStore('db4', 'keyval');
promisifyRequest
自己管理定制商店,這個沒搞太明白,看文檔中說既然都用到這個了不如直接使用idb 這個庫
總結
本文介紹了兩個 IndexedDB
的庫,用來解決 localStorage
存儲容量太小的問題
localforage
與 idb-keyval
之間我更喜歡 localforage
因為其與 localStorage
相似的api幾乎沒有上手成本。
如果需要更加靈活的庫可以看一下 dexie.js、PouchDB、idb、JsStore 或者 lovefield 之類的庫
以上就是彌補localStorage容量缺陷方法詳解的詳細內容,更多關于localStorage容量缺陷的資料請關注腳本之家其它相關文章!
相關文章
JavaScript必知必會(三) String .的方法來自何方
這篇文章主要介紹了JavaScript必知必會(三) String .的方法來自何方的相關資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-06-06JavaScript中函數聲明與函數表達式的區(qū)別詳解
可能很多朋友只知道兩種聲明方式一個是函數聲明一個是函數表達式,具體有什么不同沒能說得很好。事實上,JavaScript的解析器對函數聲明與函數表達式并不是一視同仁地對待的。下面看看這兩者到底有什么不同。2016-08-08