ä½¿ç¨ IndexedDB
IndexedDB æ¯ä¸ç§å¯å¨ç¨æ·æµè§å¨ä¸æä¹ åå卿°æ®çæ¹å¼ãå®è®©ä½ å³ä½¿å¨ç½ç»ä¸å¯ç¨æ¶ï¼ä¹è½æå»ºå ·å¤ä¸°å¯æ¥è¯¢è½åç Web åºç¨ï¼å æ¤åºç¨å¯ä»¥åæ¶å¨å¨çº¿åç¦»çº¿åºæ¯ä¸å·¥ä½ã
å ³äºæ¬ææ¡£
æ¬æç¨å°å¸¦ä½ äºè§£å¦ä½ä½¿ç¨ IndexedDB ç弿¥ APIãå¦æä½ è¿ä¸çæ IndexedDBï¼å»ºè®®å é 读 IndexedDB çå ³é®ç¹æ§ååºæ¬æ¯è¯ä¸æã
æå ³ IndexedDB API çåèææ¡£ï¼åè§ IndexedDB API åå ¶å页é¢ãæ¬æè®°å½äº IndexedDB 使ç¨ç对象类åå弿¥ API æ¹æ³ï¼åæ¥ API å·²ä»è§èä¸ç§»é¤ï¼ã
åºæ¬æ¨¡å¼
IndexedDB æ¨èçåºæ¬æ¨¡å¼å¦ä¸ï¼
- æå¼æ°æ®åºã
- 卿°æ®åºä¸å建对象åå¨ã
- å¯å¨äºå¡å¹¶å起请æ±ï¼æ§è¡æ°æ®åºæä½ï¼ä¾å¦æ·»å æè¯»åæ°æ®ï¼ã
- éè¿ç嬿£ç¡®ç±»åç DOM äºä»¶ï¼çå¾ æä½å®æã
- å¤çç»æï¼ç»æå¯å¨ request 对象ä¸åå¾ï¼ã
ææ¡äºè¿äºå¤§æ¹åä¹åï¼å°±å¯ä»¥è¿å ¥æ´å ·ä½çå 容äºã
å建并ç»ç»å¯¹è±¡åå¨
>æå¼æ°æ®åº
æ´ä¸ªæµç¨ä»è¿éå¼å§ï¼
// æå¼æ°æ®åº
const request = window.indexedDB.open("MyTestDatabase", 3);
çå°äºåï¼æå¼æ°æ®åºåå ¶ä»æä½ä¸æ ·ï¼ä½ éè¦åèµ·ä¸ä¸ªâ请æ±âã
open 请æ±ä¸ä¼ç«å³æå¼æ°æ®åºï¼ä¹ä¸ä¼ç«å»å¼å§äºå¡ãè°ç¨ open() ä¼è¿åä¸ä¸ª IDBOpenDBRequest 对象ï¼å
¶ä¸å
å«ç»æï¼æåæ¶ï¼æé误å¼ï¼ä½ éè¦éè¿äºä»¶æ¥å¤çãIndexedDB ä¸å¤§å¤æ°å¼æ¥å½æ°ä¹æ¯è¿æ ·ï¼è¿åä¸ä¸ªå
å«ç»ææé误ç IDBRequest 对象ãopen() çç»ææ¯ IDBDatabase å®ä¾ã
open æ¹æ³ç第äºä¸ªåæ°æ¯æ°æ®åºçæ¬ãæ°æ®åºçæ¬å³å®äºæ°æ®åºç模å¼ï¼ä¹å°±æ¯æ°æ®åºä¸ç对象åå¨åå
¶ç»æãå¦ææ°æ®åºå°ä¸åå¨ï¼open æä½ä¼å
å建å®ï¼ç¶å触å onupgradeneeded äºä»¶ï¼ä½ éè¦å¨è¯¥äºä»¶å¤çå¨ä¸æå¨åå»ºæ°æ®åºæ¨¡å¼ãå¦ææ°æ®åºå·²åå¨ï¼ä½ä½ ä¼ å
¥äºæ´é«ççæ¬å·ï¼ä¹ä¼ç«å»è§¦å onupgradeneededï¼è®©ä½ å¨å¤çå¨ä¸æä¾æ´æ°åçæ¨¡å¼ãæä»¬ç¨åä¼å¨ä¸æåå»ºææ´æ°æ°æ®åºçæ¬ä¸èä¸è¯¦ç»è¯´æï¼å¦è¯·åè§ IDBFactory.open åè页é¢ã
è¦åï¼çæ¬å·æ¯æ´æ°ï¼å æ¤ä¼ å
¥å¼ä¼è¢«åæ´ãä¾å¦ï¼2.1 å 2.4 é½ä¼è¢«åæ´ä¸º 2ãå¦æä½ å°è¯å¨ä¼è¢«åæ´ä¸ºå䏿´æ°ççæ¬ä¹é´å级ï¼å°±ä¸ä¼è§¦å onupgradeneeded äºä»¶ãèå¦æä½¿ç¨è¾å¤§ççæ¬å·ï¼è¿è¯·æ³¨æ JavaScript ä¸å¯è¡¨ç¤ºçæ´æ°èå´ã
设置å¤çå¨
对äºå 乿æè¯·æ±ï¼ä½ é½åºé¦å ä¸ºå ¶æ·»å æåå失败çå¤çå¨ï¼
request.onerror = (event) => {
// ä½¿ç¨ request.error åäºå¤çï¼
};
request.onsuccess = (event) => {
// ä½¿ç¨ request.result åäºå¤çï¼
};
å¦æè¯·æ±æåï¼ä¼è§¦å success äºä»¶ï¼å¹¶è°ç¨èµç» onsuccess åæ°ç彿°ã请æ±å¤±è´¥æ¶ï¼ä¼è§¦å error äºä»¶ï¼å¹¶è°ç¨èµç» onerror åæ°ç彿°ã
IndexedDB API çè®¾è®¡ç®æ ä¹ä¸æ¯å°½éåå°ä½ 对é误å¤ççéæ±ï¼å æ¤ä½ é常ä¸ä¼é¢ç¹éå°é误äºä»¶ï¼è³å°å¨ä½ çæ API åæ¯è¿æ ·ï¼ãä½å¨æå¼æ°æ®åºæ¶ï¼ç¡®å®æä¸äºå¸¸è§æ åµä¼è§¦åé误äºä»¶ãæå¸¸è§çé®é¢æ¯ï¼ç¨æ·ä¸å è®¸ä½ ç Web åºç¨åå»ºæ°æ®åºãIndexedDB çæ ¸å¿è®¾è®¡ç®æ ä¹ä¸ï¼å°±æ¯å 许为离线使ç¨åå¨å¤§éæ°æ®ãï¼å ³äºåæµè§å¨å¯ç¨åå¨éï¼åè§âæµè§å¨åå¨éå¶ä¸æ¸ çæ åâä¸çå¯ä»¥åå¨å¤å°æ°æ®ä¸èãï¼
æ¾ç¶ï¼æµè§å¨ä¸å¸æå¹¿åç½ç»ææ¶æç½ç«æ±¡æä½ çè®¡ç®æºï¼å æ¤æµè§å¨è¿å»ä¼å¨æä¸ª Web åºç¨é¦æ¬¡å°è¯æå¼ IndexedDB è¿è¡å卿¶è¯¢é®ç¨æ·ãç¨æ·å¯ä»¥å 许ææç»ãå¦å¤ï¼å¨æµè§å¨éç§æ¨¡å¼ä¸ï¼IndexedDB åå¨åªä¼å¨éç§ä¼è¯æªå ³éåå¨å åä¸ä¿çã
ç°å¨åè®¾ç¨æ·å
许äºåå»ºæ°æ®åºç请æ±ï¼å¹¶ä¸ä½ å·²ç»æ¶å°æåäºä»¶å¹¶è§¦åäºæååè°ï¼ä¸ä¸æ¥æ¯ä»ä¹ï¼è¿éçè¯·æ±æ¥èª indexedDB.open()ï¼å æ¤ request.result æ¯ IDBDatabase å®ä¾ï¼ä½ è¯å®è¦æå®ä¿å䏿¥ä¾åç»ä½¿ç¨ã代ç 大æ¦å¦ä¸ï¼
let db;
const request = indexedDB.open("MyTestDatabase");
request.onerror = (event) => {
console.error("为ä»ä¹ä¸è®©æä»¬ç Web åºç¨ä½¿ç¨ IndexedDBï¼ï¼");
};
request.onsuccess = (event) => {
db = event.target.result;
};
é误å¤ç
å¦ä¸æè¿°ï¼é误äºä»¶ä¼å泡ãé误äºä»¶å åå¾è§¦åé误ç请æ±ï¼ååæ³¡å°äºå¡ï¼æåå°æ°æ®åºå¯¹è±¡ãå¦æä½ ä¸æ³ç»æ¯ä¸ªè¯·æ±é½å é误å¤çå¨ï¼å¯ä»¥å¨æ°æ®åºå¯¹è±¡ä¸ç»ä¸å ä¸ä¸ªï¼
db.onerror = (event) => {
// éå¯¹æ¤æ°æ®åºè¯·æ±çææé误çéç¨å¤çå¨ï¼
console.error(`æ°æ®åºé误ï¼${event.target.error?.message}`);
};
æå¼æ°æ®åºæ¶å¸¸è§é误ä¹ä¸æ¯ VER_ERRãè¿è¡¨ç¤ºç£ç䏿°æ®åºççæ¬é«äºä½ å°è¯æå¼ççæ¬ãè¿ç±»é误å¿
é¡»å§ç»å¨é误å¤çå¨ä¸å¤çã
åå»ºææ´æ°æ°æ®åºçæ¬
å½ä½ åå»ºæ°æ°æ®åºææé«ç°ææ°æ®åºçæ¬å·æ¶ï¼å³å¨æå¼æ°æ®åºæ¶æå®æ¯ä¹åæ´é«ççæ¬å·ï¼ï¼ä¼è§¦å onupgradeneeded äºä»¶ï¼å¹¶åè®¾ç½®å¨ request.resultï¼ä¹å°±æ¯ç¤ºä¾ä¸ç dbï¼ä¸çä»»æ onversionchange äºä»¶å¤çå¨ä¼ éä¸ä¸ª IDBVersionChangeEvent 对象ãå¨ upgradeneeded äºä»¶å¤çå¨ä¸ï¼ä½ åºåå»ºè¯¥æ°æ®åºçæ¬æéç对象åå¨ï¼
// 该äºä»¶ä»
å¨è¾æ°çæµè§å¨ä¸å®ç°
request.onupgradeneeded = (event) => {
// ä¿å IDBDatabase æ¥å£
const db = event.target.result;
// ä¸ºè¯¥æ°æ®åºå建对象åå¨
const objectStore = db.createObjectStore("name", { keyPath: "myKey" });
};
è¿ç§æ
åµä¸ï¼æ°æ®åºå·²å
嫿§çæ¬ä¸ç对象åå¨ï¼æä»¥ä¸éè¦éå¤å建ãä½ åªéè¦å建æ°å¯¹è±¡åå¨ï¼æå 餿§çæ¬ä¸ä¸åéè¦ç对象åå¨ã妿éè¦ä¿®æ¹å·²æå¯¹è±¡åå¨ï¼ä¾å¦æ´æ¹ keyPathï¼ï¼å¿
é¡»å 餿§å¯¹è±¡åå¨ï¼åç¨æ°é项鿰å建ãï¼æ³¨æï¼è¿ä¼å é¤å¯¹è±¡åå¨ä¸çä¿¡æ¯ï¼å¦æéè¦ä¿çï¼å级åéè¦å
读åºå¹¶å¦åãï¼
å°è¯å建ä¸ä¸ªå·²åå¨åç§°ç对象åå¨ï¼æå é¤ä¸ä¸ªä¸åå¨åç§°ç对象åå¨ï¼é½ä¼æåºé误ã
妿 onupgradeneeded äºä»¶æåéåºï¼æå¼æ°æ®åºè¯·æ±ç onsuccess å¤çå¨éåä¼è¢«è§¦åã
ç»ç»æ°æ®åºç»æ
ä¸é¢æ¥ç»ç»æ°æ®åºç»æãIndexedDB 使ç¨å¯¹è±¡åå¨èé表ï¼å¹¶ä¸ä¸ä¸ªæ°æ®åºå¯ä»¥å å«ä»»ææ°éç对象åå¨ãæ¯å½å¼åå ¥å¯¹è±¡åå¨ï¼å®é½ä¼å ³èä¸ä¸ªé®ãé®çæä¾æ¹å¼åå³äºå¯¹è±¡å卿¯å¦ä½¿ç¨é®è·¯å¾æé®çæå¨ã
ä¸è¡¨å±ç¤ºäºé®çä¸åæä¾æ¹å¼ï¼
é®è·¯å¾ï¼keyPathï¼ |
é®çæå¨ï¼autoIncrementï¼ |
æè¿° |
|---|---|---|
| å¦ | å¦ | 该对象åå¨å¯ä»¥ä¿åä»»ä½ç±»åçå¼ï¼å æ¬æ°åãå符串çåå§å¼ãæ¯æ¬¡æ·»å æ°å¼æ¶é½å¿ é¡»åç¬æä¾é®åæ°ã |
| æ¯ | å¦ | 该对象åå¨åªè½ä¿å JavaScript 对象ï¼è¿äºå¯¹è±¡å¿ é¡»æ¥æä¸é®è·¯å¾ååç屿§ã |
| å¦ | æ¯ | 该对象åå¨å¯ä»¥ä¿åä»»ä½ç±»åçå¼ãé®ä¼èªå¨çæï¼å¦æä½ æ³ä½¿ç¨ç¹å®é®ï¼ä¹å¯ä»¥åç¬æä¾é®åæ°ã |
| æ¯ | æ¯ | 该对象åå¨åªè½ä¿å JavaScript 对象ãé常ä¼èªå¨çæé®ï¼å¹¶å°è¯¥é®å¼åå ¥å¯¹è±¡ä¸ä¸é®è·¯å¾ååç屿§ãå¦æè¯¥å±æ§å·²åå¨ï¼åä¼ä½¿ç¨è¯¥å±æ§å¼ä½ä¸ºé®èä¸ä¼åçææ°é®ã |
åªè¦å¯¹è±¡åå¨ä¿åçæ¯å¯¹è±¡ï¼èéåå§å¼ï¼ï¼ä½ è¿å¯ä»¥å¨å ¶ä¸å建索å¼ãç´¢å¼å è®¸ä½ æå¯¹è±¡æä¸ªå±æ§å¼æ¥æ¾å¯¹è±¡åå¨ä¸çå¼ï¼è䏿¯æå¯¹è±¡é®æ¥æ¾ã
æ¤å¤ï¼ç´¢å¼è¿è½å¯¹å卿°æ®æ½å ç®å约æãåå»ºç´¢å¼æ¶è®¾ç½® unique æ å¿åï¼ç´¢å¼ä¼ä¿è¯ä¸ä¼æä¸¤ä¸ªå¯¹è±¡å¨è¯¥ç´¢å¼é®è·¯å¾ä¸å ·æç¸åå¼ã举个ä¾åï¼å¦æå¯¹è±¡åå¨ä¿åçæ¯äººåä¿¡æ¯ï¼å¹¶ä¸ä½ 叿ä¸åºç°ä¸¤ä¸ªç¸åé®ç®±å°åï¼å°±å¯ä»¥å建带 unique æ å¿çç´¢å¼æ¥å¼ºå¶çº¦æã
è¿å¬èµ·æ¥å¯è½æç¹ä»¤äººå°æï¼ä½ä¸é¢è¿ä¸ªç®å示ä¾å¯ä»¥è¯´æè¿äºæ¦å¿µãå å®ä¹ç¤ºä¾ç¨çå®¢æ·æ°æ®ï¼
// æä»¬çå®¢æ·æ°æ®å¦ä¸
const customerData = [
{ ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com" },
{ ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org" },
];
å½ç¶ï¼ä½ é常ä¸ä¼æç¤¾ä¿å·å½å®¢æ·è¡¨ä¸»é®ï¼å ä¸ºå¹¶éææäººé½æç¤¾ä¿å·ï¼èä¸ä½ ä¼åå¨åºçæ¥æè䏿¯å¹´é¾ãä½ä¸ºäºæ¼ç¤ºæ¹ä¾¿ï¼æä»¬å 忽ç¥è¿äºä¸çæ³çéæ©ã
ç°å¨çå¦ä½å建ä¸ä¸ªç¨äºåå¨è¿äºæ°æ®ç IndexedDBï¼
const dbName = "the_name";
const request = indexedDB.open(dbName, 2);
request.onerror = (event) => {
// å¤çé误ã
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
// å建对象åå¨ä¿å客æ·ä¿¡æ¯ãæä»¬å°ä½¿ç¨âssnâä½ä¸ºé®è·¯å¾ï¼å 为å®ä¿è¯å¯ä¸ââè³å°é¡¹ç®å¯å¨ä¼æ¯è¿ä¹è¯´çã
const objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
// æå§åå建索å¼ãå§åå¯è½éå¤ï¼æä»¥ä¸è½ä½¿ç¨å¯ä¸ç´¢å¼ã
objectStore.createIndex("name", "name", { unique: false });
// æé®ç®±å建索å¼ãæä»¬å¸æé®ç®±ä¸éå¤ï¼æä»¥ä½¿ç¨å¯ä¸ç´¢å¼ã
objectStore.createIndex("email", "email", { unique: true });
// ä½¿ç¨ transaction ç oncompleteï¼ç¡®ä¿å¯¹è±¡åå¨åå»ºå®æåååå
¥æ°æ®ã
objectStore.transaction.oncomplete = (event) => {
// æå¼åå
¥æ°å»ºç对象åå¨ã
const customerObjectStore = db
.transaction("customers", "readwrite")
.objectStore("customers");
customerData.forEach((customer) => {
customerObjectStore.add(customer);
});
};
};
å¦åæè¿°ï¼onupgradeneeded æ¯å¯ä¸å¯ä»¥ä¿®æ¹æ°æ®åºç»æçå°æ¹ãä½ å¯ä»¥å¨è¿éå建åå é¤å¯¹è±¡åå¨ï¼æå¨æ¤å建åå é¤ç´¢å¼ã
对象åå¨éè¿ä¸æ¬¡ createObjectStore() è°ç¨å建ãè¯¥æ¹æ³æ¥æ¶åå¨åç§°ååæ°å¯¹è±¡ãåæ°å¯¹è±¡è½ç¶å¯éï¼ä½å¾éè¦ï¼å 为å®è½è®©ä½ å®ä¹å
³é®å¯é屿§ï¼ç²¾ç¡®æå®è¦å建ç对象åå¨ç±»åã示ä¾ä¸æä»¬å建äºå为âcustomersâç对象åå¨ï¼å¹¶å®ä¹äº keyPathãkeyPath 对åºç屿§å³å®äºåå¨ä¸æ¯ä¸ªå¯¹è±¡çå¯ä¸æ§ãè¿éæ¯âssnâï¼å 为社ä¿å·è¢«è®¤ä¸ºæ¯å¯ä¸çãåå
¥ objectStore çæ¯ä¸ªå¯¹è±¡é½å¿
é¡»å
å«âssnâã
æä»¬è¿å建äºå为ânameâçç´¢å¼ï¼ç¨äºç´¢å¼å¯¹è±¡ä¸ç name 屿§ãå createObjectStore() 䏿 ·ï¼createIndex() 乿¥æ¶ä¸ä¸ªå¯éç options 对象ï¼ç¨äºç»åç´¢å¼ç±»åãå³ä½¿æ·»å ç对象没æ name 屿§ä¹ä¼æåï¼ä½è¯¥å¯¹è±¡ä¸ä¼åºç°å¨ânameâç´¢å¼ä¸ã
ç°å¨æä»¬å¯ä»¥ç´æ¥éè¿å¯¹è±¡åå¨ä¸ç ssn è·å客æ·å¯¹è±¡ï¼æè
éè¿ç´¢å¼æå§åæ¥æ¾ãå
·ä½åæ³è§ä½¿ç¨ç´¢å¼ä¸èã
使ç¨é®çæå¨
å¨å建对象å卿¶è®¾ç½® autoIncrement æ å¿ï¼ä¼ä¸ºè¯¥å¯¹è±¡åå¨å¯ç¨é®çæå¨ãé»è®¤ä¸å¯ç¨ã
å¯ç¨é®çæå¨åï¼å对象å卿°å¢å¼æ¶ä¼èªå¨çæé®ã对象åå¨é¦æ¬¡å建æ¶ï¼é®çæå¨å½åå¼å§ç»è®¾ä¸º 1ãä¹åæ¯æ¬¡èªå¨çæçæ°é®ï¼é½ä¼å¨åä¸ä¸ªé®åºç¡ä¸èªå¢å 1ãé¤éæ°æ®åºæä½è¢«åæ»ï¼ä¾å¦äºå¡è¢«ä¸æ¢ï¼ï¼å¦åé®çæå¨å½åå¼ä¸ä¼åå°ãå æ¤ï¼å é¤è®°å½ï¼çè³æ¸ 空对象åå¨ï¼é½ä¸ä¼å½±åé®çæå¨ã
æä»¬å¯ä»¥åä¸é¢è¿æ ·å建å¦ä¸ä¸ªå¯ç¨é®çæå¨ç对象åå¨ï¼
// æå¼ indexedDBã
const request = indexedDB.open(dbName, 3);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// å建å¦ä¸ä¸ªå为ânamesâç对象åå¨ï¼å¹¶å° autoIncrement 设为 trueã
const objStore = db.createObjectStore("names", { autoIncrement: true });
// å 为ânamesâ对象åå¨å¯ç¨äºé®çæå¨ï¼æä»¥ name çé®ä¼èªå¨çæãæ·»å åçè®°å½ç±»ä¼¼äºï¼
// é®ï¼1 => å¼ï¼âBillâ
// é®ï¼2 => å¼ï¼âDonnaâ
customerData.forEach((customer) => {
objStore.add(customer.name);
});
};
å ³äºé®çæå¨çæ´å¤ç»èï¼è¯·åè§è§èä¸çé®çæå¨ä¸èã
æ·»å ãæ£ç´¢åå 餿°æ®
å¨å¯¹æ°æ°æ®åºæ§è¡ä»»ä½æä½åï¼ä½ éè¦å
å¼å¯äºå¡ãäºå¡ç±æ°æ®åºå¯¹è±¡å建ï¼ä½ å¿
é¡»æå®äºå¡è¦çåªäºå¯¹è±¡åå¨ãè¿å
¥äºå¡åï¼ä½ å°±å¯ä»¥è®¿é®ä¿åæ°æ®ç对象åå¨å¹¶å起请æ±ãæ¥ä¸æ¥ï¼ä½ éè¦å³å®æ¯ä¿®æ¹æ°æ®åºï¼è¿æ¯åªè¯»åæ°æ®ãäºå¡æä¸ç§å¯ç¨æ¨¡å¼ï¼readonlyãreadwrite å versionchangeã
è¦ä¿®æ¹æ°æ®åºçâæ¨¡å¼âæç»æï¼å
æ¬å建æå é¤å¯¹è±¡åå¨ãç´¢å¼ï¼ï¼äºå¡å¿
é¡»å¤äº versionchange 模å¼ãè¿ä¸ªäºå¡éè¿è°ç¨æå® version ç IDBFactory.open æ¹æ³å¼å¯ã
è¦è¯»åå·²æå¯¹è±¡åå¨ä¸çè®°å½ï¼äºå¡å¯ä»¥æ¯ readonly æ readwriteï¼è¦ä¿®æ¹å·²æå¯¹è±¡åå¨ï¼äºå¡å¿
é¡»æ¯ readwriteãè¿ç±»äºå¡éè¿ IDBDatabase.transaction æå¼ãè¯¥æ¹æ³æ¥æ¶ä¸¤ä¸ªåæ°ï¼storeNamesï¼ä½ç¨åï¼å®ä¹ä¸ºä½ è¦è®¿é®ç对象åå¨çæ°ç»ï¼åäºå¡ modeï¼readonly æ readwriteï¼ãæ¹æ³è¿åäºå¡å¯¹è±¡ï¼å
¶ä¸å
å« IDBIndex.objectStore æ¹æ³ï¼ä½ å¯ä»¥ç¨å®è®¿é®å¯¹è±¡åå¨ãé»è®¤æ
åµä¸ï¼å¦ææªæå® modeï¼äºå¡ä¼ä»¥ readonly æ¨¡å¼æå¼ã
夿³¨ï¼ä» Firefox 40 å¼å§ï¼IndexedDB äºå¡æ¾å®½äºæä¹
æ§ä¿è¯ä»¥æåæ§è½ï¼è§ Firefox bug 1112702ï¼ãæ¤åå¨ readwrite äºå¡ä¸ï¼åªæå½æææ°æ®é½ç¡®ä¿å·²å·çæ¶æä¼è§¦å complete äºä»¶ãå¨ Firefox 40+ ä¸ï¼complete äºä»¶ä¼å¨æä½ç³»ç»æ¶å°åå
¥æä»¤å触åï¼ä½æ¤æ¶æ°æ®å¯è½å°æªçæ£åå
¥ç£çãå æ¤ complete äºä»¶å¯è½æ¯è¿å»æ´æ©å°è¾¾ï¼ä½è¥å¨æ°æ®å·çåæä½ç³»ç»å´©æºæåçæçµï¼æ´ä¸ªäºå¡ä¼ä»¥æå°æ¦ç丢失ãç±äºè¿ç±»ç¾é¾æ§äºä»¶å¾å°è§ï¼å¤§å¤æ°åºæ¯æ éé¢å¤æ
å¿ãå¦æä½ å¿
é¡»ç¡®ä¿æä¹
æ§ï¼ä¾å¦å卿 æ³éç®çå
³é®æ°æ®ï¼ï¼å¯ä½¿ç¨å®éªæ§çï¼éæ åï¼readwriteflush 模å¼å建äºå¡ï¼ä»¥å¼ºå¶å¨è§¦å complete äºä»¶åå
å·çï¼è§ IDBDatabase.transactionï¼ã
éè¿éæ©åéçäºå¡ä½ç¨å忍¡å¼ï¼å¯ä»¥å éæ°æ®è®¿é®ãè¿éæä¸¤æ¡å»ºè®®ï¼
- å®ä¹ä½ç¨åæ¶ï¼åªæå®ä½ éè¦ç对象åå¨ãè¿æ ·ä½ å¯ä»¥å¹¶åæ§è¡å¤ä¸ªä½ç¨åä¸éå çäºå¡ã
- ä»
å¨å¿
è¦æ¶ä½¿ç¨
readwrite模å¼ãä½ å¯ä»¥å¹¶åæ§è¡å¤ä¸ªä½ç¨åéå çreadonlyäºå¡ï¼ä½åä¸å¯¹è±¡åå¨å䏿¶å»åªè½æä¸ä¸ªreadwriteäºå¡ãæ´å¤ä¿¡æ¯è§ IndexedDB çå ³é®ç¹æ§ååºæ¬æ¯è¯ä¸æä¸ transaction çå®ä¹ã
åæ°æ®åºæ·»å æ°æ®
å¦æä½ ååå»ºäºæ°æ®åºï¼é常æ¥ä¸æ¥å°±æ³åæ°æ®ãåæ³å¦ä¸ï¼
const transaction = db.transaction(["customers"], "readwrite");
// 注æï¼è¾èçå®éªæ§å®ç°ä½¿ç¨å·²å¼ç¨å¸¸é IDBTransaction.READ_WRITEï¼è䏿¯âreadwriteâãå¦æä½ è¦å
¼å®¹è¿ç±»å®ç°ï¼å¯ä»¥åæï¼
// const transaction = db.transaction(["customers"], IDBTransaction.READ_WRITE);
transaction() 彿°æ¥æ¶ä¸¤ä¸ªåæ°ï¼å
¶ä¸ä¸ä¸ªå¯éï¼ï¼å¹¶è¿åäºå¡å¯¹è±¡ã第ä¸ä¸ªåæ°æ¯äºå¡è¦è¦çç对象åå¨å表ãå¦æä½ æ³è®©äºå¡è¦çå
¨é¨å¯¹è±¡åå¨ï¼å¯ä»¥ä¼ 空æ°ç»ï¼ä½ä¸è¦è¿ä¹åï¼å 为è§èè§å®ç©ºæ°ç»åºè§¦å InvalidAccessErrorã第äºä¸ªåæ°è¥ä¸ä¼ ï¼å¾å°çæ¯åªè¯»äºå¡ãè¿éä½ è¦åå
¥ï¼æä»¥éè¦ä¼ å
¥ "readwrite"ã
æäºäºå¡ä¹åï¼ä½ è¿éè¦çè§£å®ççå½å¨æãäºå¡ä¸äºä»¶å¾ªç¯ç´§å¯ç¸å
³ï¼å¦æå建äºå¡åç´æ¥åå°äºä»¶å¾ªç¯è没æä½¿ç¨å®ï¼äºå¡ä¼åä¸ºéæ´»å¨ç¶æãä¿æäºå¡æ´»å¨çå¯ä¸æ¹å¼æ¯å¨å
¶ä¸å起请æ±ã请æ±ç»æåä½ ä¼æ¶å°ä¸ä¸ª DOM äºä»¶ï¼è¥è¯·æ±æåï¼ä½ å°±ææºä¼å¨è¯¥åè°ä¸ç»§ç»å»¶é¿äºå¡ãå¦æä½ å¨æªå»¶é¿äºå¡æ¶è¿åäºä»¶å¾ªç¯ï¼äºå¡å°±ä¼å¤±æ´»ï¼å¦æ¤å¾å¤ãåªè¦è¿æå¾
å¤ç请æ±ï¼äºå¡å°±ä¿ææ´»å¨ãäºå¡çå½å¨æå
¶å®å¾ç®åï¼ä½ç¡®å®éè¦ä¸ç¹æ¶é´éåºãå¤çå 个ä¾å伿叮å©ãå¦æä½ å¼å§éå° TRANSACTION_INACTIVE_ERRï¼è¯´ææå¤åºéäºã
äºå¡å¯æ¥æ¶ä¸ç±» DOM äºä»¶ï¼errorãabort å completeãåé¢æè¿ error ä¼å泡ï¼å æ¤äºå¡ä¼æ¥æ¶å°å
¶å建ç请æ±äº§ççéè¯¯ãæ´å¾®å¦çä¸ç¹æ¯ï¼é误çé»è®¤è¡ä¸ºæ¯ä¸æ¢åçé误çäºå¡ãé¤éä½ å
对é误äºä»¶è°ç¨ stopPropagation() å¹¶å¦è¡å¤çï¼å¦åæ´ä¸ªäºå¡ä¼åæ»ãè¿æ ·ç设计ä¼è¿«ä½¿ä½ 认çèèå¹¶å¤çé误ï¼å¦æç»ç²åº¦å¤ç太ç¹çï¼ä¹å¯ä»¥å¨æ°æ®åºå¯¹è±¡ä¸æ·»å å
åºé误å¤çå¨ãå¦æä½ ä¸å¤çé误äºä»¶ï¼æè°ç¨äºäºå¡ç abort()ï¼äºå¡ä¼åæ»ï¼å¹¶å¨äºå¡ä¸è§¦å abort äºä»¶ãå¦å卿æå¾
å¤ç请æ±å®æåï¼ä½ 伿¶å° complete äºä»¶ãå¦æä½ å¨å大鿰æ®åºæä½ï¼è·è¸ªäºå¡è䏿¯é个è·è¸ªè¯·æ±ï¼é常æ´çå¿ã
ç°å¨ä½ å·²ç»æäºå¡äºï¼æ¥ä¸æ¥è¦ä»äºå¡ä¸è·å对象åå¨ãäºå¡åªå è®¸ä½ è®¿é®å建äºå¡æ¶æå®ç对象åå¨ãç¶åä½ å°±å¯ä»¥æ·»å æéæ°æ®ã
// å½æææ°æ®é½æ·»å å°æ°æ®åºåæ§è¡æäºæä½ã
transaction.oncomplete = (event) => {
console.log("å·²ç»å¤çå®äºï¼");
};
transaction.onerror = (event) => {
// å«å¿äºå¤çé误ï¼
};
const objectStore = transaction.objectStore("customers");
customerData.forEach((customer) => {
const request = objectStore.add(customer);
request.onsuccess = (event) => {
// event.target.result === customer.ssn;
};
});
è°ç¨ add() 产çè¯·æ±æ¶ï¼è¿å请æ±ç result æ¯è¢«æ·»å å¼çé®ãæä»¥æ¬ä¾ä¸å®åºçäºè¢«æ·»å 对象ç ssn 屿§ï¼å 为该对象åå¨ä½¿ç¨ ssn ä½ä¸ºé®è·¯å¾ã注æï¼add() è¦æ±æ°æ®åºä¸ä¸åå¨åé®å¯¹è±¡ãå¦æä½ æ³ä¿®æ¹å·²ææ¡ç®ï¼æä¸å¨æå®æ¯å¦å·²åå¨ï¼å¯ä»¥ä½¿ç¨ put()ï¼è§ä¸ææ´æ°æ°æ®åºä¸çæ¡ç®ä¸èã
仿°æ®åºä¸å 餿°æ®
å 餿°æ®é常类似ï¼
const request = db
.transaction(["customers"], "readwrite")
.objectStore("customers")
.delete("444-44-4444");
request.onsuccess = (event) => {
// å·²å é¤ï¼
};
仿°æ®åºä¸è·åæ°æ®
æ°æ®åºä¸å·²ç»ææ°æ®åï¼ä½ å¯ä»¥ç¨å¤ç§æ¹å¼ååãæç®åçæ¯ get()ãä½ éè¦æä¾é®æ¥è·å对åºå¼ï¼
const transaction = db.transaction(["customers"]);
const objectStore = transaction.objectStore("customers");
const request = objectStore.get("444-44-4444");
request.onerror = (event) => {
// å¤çé误ï¼
};
request.onsuccess = (event) => {
// 对 request.result åäºå¤çï¼
console.log(`社ä¿å·ä¸º 444-44-4444 ç顾客å为 ${request.result.name}`);
};
对âç®åâè¯»åæ¥è¯´ï¼è¿æ®µä»£ç çèµ·æ¥æç¹é¿ãåè®¾ä½ å¨æ°æ®åºçº§ç»ä¸å¤çé误ï¼å¯ä»¥ç¼©çæè¿æ ·ï¼
db
.transaction("customers")
.objectStore("customers")
.get("444-44-4444").onsuccess = (event) => {
console.log(`社ä¿å·ä¸º 444-44-4444 ç顾客å为 ${event.target.result.name}`);
};
çåºæ¥äºåï¼å 为è¿éåªç¨ä¸ä¸ªå¯¹è±¡åå¨ï¼æä»¥ä¸å¿
ä¼ å¯¹è±¡åå¨å表ï¼ç´æ¥ä¼ åç§°å符串å³å¯ãå¦å¤è¿éåªè¯»æ°æ®ï¼ä¸éè¦ "readwrite" äºå¡ãä¸ä¼ mode è°ç¨ transaction()ï¼ä¼å¾å° "readonly" äºå¡ãè¿æä¸ªå°ç»èï¼ä½ ä¸ä¸å®è¦æè¯·æ±å¯¹è±¡åå
¥åéãå 为 DOM äºä»¶ç target å°±æ¯è¯·æ±å¯¹è±¡ï¼ä½ å¯ä»¥éè¿äºä»¶ç´æ¥è®¿é® resultã
æ´æ°æ°æ®åºä¸çæ¡ç®
æ¿å°æ°æ®åï¼ä¿®æ¹å¹¶åå IndexedDB å¾ç®åãæä»¬ç¨å¾®æ¹é ä¸ä¸åé¢ç示ä¾ï¼
const objectStore = db
.transaction(["customers"], "readwrite")
.objectStore("customers");
const request = objectStore.get("444-44-4444");
request.onerror = (event) => {
// å¤çé误ï¼
};
request.onsuccess = (event) => {
// è·åè¦æ´æ°çæ§å¼
const data = event.target.result;
// æ´æ°å¯¹è±¡ä¸ä½ æ³ä¿®æ¹çå¼
data.age = 42;
// å°æ´æ°åç对象æ¾åæ°æ®åº
const requestUpdate = objectStore.put(data);
requestUpdate.onerror = (event) => {
// å¤çé误
};
requestUpdate.onsuccess = (event) => {
// æåï¼æ°æ®å·²æ´æ°ï¼
};
};
è¿éæä»¬å
å建 objectStoreï¼å¹¶ç¨ ssn å¼ï¼444-44-4444ï¼ååºå®¢æ·è®°å½ãç¶åæç»ææ¾è¿åé dataï¼æ´æ°å
¶ age 屿§ï¼åå建第äºä¸ªè¯·æ± requestUpdateï¼å°å®¢æ·è®°å½åå objectStoreï¼è¦çæ§å¼ã
夿³¨ï¼è¿éå¿
é¡»æå® readwrite äºå¡ï¼å 为æä»¬è¦åæ°æ®åºï¼èä¸ä»
ä»
æ¯è¯»åã
ä½¿ç¨æ¸¸æ
ä½¿ç¨ get() çåææ¯ä½ ç¥éè¦æ¥åªä¸ªé®ãå¦æä½ æ³éå对象åå¨ä¸çææå¼ï¼å¯ä»¥ä½¿ç¨æ¸¸æ ã示ä¾å¦ä¸ï¼
const objectStore = db.transaction("customers").objectStore("customers");
objectStore.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log(`社ä¿å·ä¸º ${cursor.key} ç顾客å为 ${cursor.value.name}`);
cursor.continue();
} else {
console.log("æ²¡ææ´å¤è®°å½ï¼");
}
};
openCursor() å¯ä»¥æ¥æ¶å¤ä¸ªåæ°ãé¦å
ï¼ä½ å¯ä»¥ç¨é®èå´å¯¹è±¡éå¶ååæ¡ç®çèå´ï¼ç¨åä¼ä»ç»ï¼ãå
¶æ¬¡ï¼ä½ å¯ä»¥æå®è¿ä»£æ¹åãä¸ä¾æååºéåææå¯¹è±¡ãæ¸¸æ ç success åè°ç¨å¾®ç¹æ®ï¼æ¸¸æ 对象æ¬èº«å°±æ¯è¯·æ±ç resultï¼ä¸é¢ä½¿ç¨äºç®åï¼å³ event.target.resultï¼ãå®é
é®åå¼åå«å¨æ¸¸æ 对象ç key å value 屿§ä¸ã妿è¦ç»§ç»éåï¼å¿
é¡»è°ç¨æ¸¸æ ç continue()ãå½å°è¾¾æ°æ®æ«å°¾ï¼ææ²¡æä»»ä½æ¡ç®å¹é
openCursor() 请æ±ï¼æ¶ä»ä¼è§¦å success åè°ï¼åªæ¯ result 为 undefinedã
ä½¿ç¨æ¸¸æ çä¸ä¸ªå¸¸è§æ¨¡å¼æ¯ååºå¯¹è±¡åå¨ä¸çææå¯¹è±¡å¹¶æ¾è¿æ°ç»ï¼
const customers = [];
objectStore.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
customers.push(cursor.value);
cursor.continue();
} else {
console.log(`è·åå°ææé¡¾å®¢ï¼${customers}`);
}
};
夿³¨ï¼å¦å¤ï¼ä½ ä¹å¯ä»¥ç¨ getAll()ï¼ä»¥å getAllKeys()ï¼å¤çè¿ç§æ
åµãä¸é¢ä»£ç ä¸ä¸é¢ä½ç¨å®å
¨ç¸åï¼
objectStore.getAll().onsuccess = (event) => {
console.log(`è·åå°ææé¡¾å®¢ï¼${event.target.result}`);
};
è¯»åæ¸¸æ ç value 屿§ä¼ææ§è½ææ¬ï¼å ä¸ºå¯¹è±¡æ¯æ°æ§å建çãæ¯å¦ä½¿ç¨ getAll() æ¶ï¼æµè§å¨å¿
须䏿¬¡æ§å建ææå¯¹è±¡ãå¦æä½ åªå
³å¿é®ï¼ç¨æ¸¸æ éå¸¸æ¯ getAll() æ´é«æãè¥ä½ å°±æ¯è¦è·å对象åå¨å
¨é¨å¯¹è±¡çæ°ç»ï¼é£ä¹ç¨ getAll()ã
使ç¨ç´¢å¼
ç¨ SSN ä½ä¸ºé®æ¥åå®¢æ·æ°æ®å¾åçï¼å 为 SSN è½å¯ä¸æ è¯ä¸ªäººãï¼è³äºè¿å¨éç§ä¸æ¯ä¸æ¯å¥½ä¸»æï¼æ¯å¦ä¸ä¸ªé®é¢ï¼ä¸å¨æ¬æèå´å ãï¼ä½å¦æä½ éè¦æå§åæ¥å®¢æ·ï¼å°±å¾éåæ°æ®åºä¸æ¯ä¸ª SSN ç´å°æ¾å°ç®æ ãè¿ç§æ¥æ¾å¾æ ¢ï¼å æ¤åºä½¿ç¨ç´¢å¼ã
// é¦å
ï¼ç¡®ä¿ä½ å·²å¨ request.onupgradeneeded ä¸å建索å¼ï¼
// objectStore.createIndex("name", "name");
// å¦åä¼æåº DOMExceptionã
const index = objectStore.index("name");
index.get("Donna").onsuccess = (event) => {
console.log(`Donna ç社ä¿å·ä¸º ${event.target.result.ssn}`);
};
ânameâç´¢å¼ä¸æ¯å¯ä¸ç´¢å¼ï¼å æ¤ name 为 "Donna" çæ¡ç®å¯è½ä¸æ¢ä¸æ¡ãæ¤æ¶ä½ æ»ä¼æ¿å°é®å¼æå°çé£ä¸æ¡ã
å¦æä½ è¦è®¿é®æä¸ª name çæææ¡ç®ï¼å¯ä»¥ä½¿ç¨æ¸¸æ ãä½ å¯ä»¥å¨ç´¢å¼ä¸æå¼ä¸¤ç±»æ¸¸æ ï¼æ®é游æ å°ç´¢å¼å±æ§æ å°å°å¯¹è±¡åå¨ä¸ç对象ï¼é®æ¸¸æ å°ç´¢å¼å±æ§æ å°å°å¯¹è±¡å¨å¯¹è±¡åå¨ä¸çé®ãåºå«å¦ä¸ï¼
// ç¨æ®éæ¸¸æ æ¿å°å®æ´å®¢æ·è®°å½å¯¹è±¡
index.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// cursor.key æ¯ååï¼å¦âBillâï¼ï¼cursor.value æ¯å®æ´å¯¹è±¡ã
console.log(
`Nameï¼${cursor.key}ï¼SSNï¼${cursor.value.ssn}ï¼emailï¼${cursor.value.email}`,
);
cursor.continue();
}
};
// ç¨é®æ¸¸æ æ¿å°å®¢æ·è®°å½å¯¹è±¡çé®
index.openKeyCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// cursor.key æ¯ååï¼å¦âBillâï¼ï¼cursor.primaryKey æ¯ SSNã
// æ æ³ç´æ¥æ¿å°å·²å对象çå
¶ä½é¨åã
console.log(`Nameï¼${cursor.key}ï¼SSNï¼${cursor.primaryKey}`);
cursor.continue();
}
};
ç´¢å¼ä¹å¯ä»¥åºäºå¤ä¸ªå±æ§å建ï¼ä»èæå¼ç»åæ¥è¯¢è®°å½ï¼ä¾å¦åæ¶æå§ååé®ç®±æ¥æ¾æäººãå建å¤åç´¢å¼æ¶ï¼å¨è°ç¨ createIndex æ¶æå±æ§åæ°ç»ä½ä¸ºé®è·¯å¾ä¼ å
¥ãä¹åæ¥è¯¢æ¶åæåæ ·é¡ºåºä¼ å
¥å¼æ°ç»ã
å
ç¡®ä¿ä½ å¨ request.onupgradeneeded ä¸å建äºç´¢å¼ï¼
const index = objectStore.createIndex("name_email", ["name", "email"]);
éåå¯ä»¥è¿æ ·æ¥è¯¢ï¼
const index = objectStore.index("name_email");
index.get(["Donna", "donna@home.org"]).onsuccess = (event) => {
console.log(event.target.result);
// {ssn: '555-55-5555', name: 'Donna', age: 32, email: 'donna@home.org'}
};
æå®æ¸¸æ çèå´åæ¹å
å¦æä½ å¸æéå¶æ¸¸æ å¯è§å¼çèå´ï¼å¯ä»¥å建 IDBKeyRange 对象ï¼å¹¶æå®ä½ä¸ºç¬¬ä¸ä¸ªåæ°ä¼ ç» openCursor() æ openKeyCursor()ãä½ å¯ä»¥å建ä»
å
许å个é®çèå´ï¼ä¹å¯ä»¥åå»ºåªæä¸çãåªæä¸çãæåæ¶æä¸ä¸ççèå´ãè¾¹çå¯ä¸ºâéåºé´âï¼å³å
å«ç»å®å¼ï¼æâå¼åºé´âï¼å³ä¸å
å«ç»å®å¼ï¼ãç¨æ³å¦ä¸ï¼
// ä»
å¹é
âDonnaâ
const singleKeyRange = IDBKeyRange.only("Donna");
// å¹é
ææå¤§äºçäºâBillâçå¼
const lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill");
// å¹é
ææå¤§äºâBillâçå¼ï¼ä¸å
æ¬âBillâ
const lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true);
// å¹é
ææå°äºâDonnaâçå¼ï¼ä¸å
æ¬âDonnaâ
const upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna", true);
// å¹é
âBillâå°âDonnaâä¹é´çå¼ï¼ä½ä¸å
æ¬âDonnaâ
const boundKeyRange = IDBKeyRange.bound("Bill", "Donna", false, true);
// 使ç¨é®èå´æ¶ï¼å°å
¶ä½ä¸º openCursor()/openKeyCursor() ç第ä¸ä¸ªåæ°
index.openCursor(boundKeyRange).onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// å¤çå¹é
ç»æã
cursor.continue();
}
};
ææ¶ä½ å¯è½å¸ææéåºèéååºï¼æææ¸¸æ é»è®¤æ¹åï¼è¿ä»£ã忢æ¹åçæ¹æ³æ¯ç» openCursor() ç第äºä¸ªåæ°ä¼ prevï¼
objectStore.openCursor(boundKeyRange, "prev").onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// å¤çæ¡ç®ã
cursor.continue();
}
};
å¦æä½ åªæ³æ¹åæ¹åèä¸éå¶ç»æï¼ç¬¬ä¸ä¸ªåæ°ç´æ¥ä¼ null å³å¯ï¼
objectStore.openCursor(null, "prev").onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// å¤çæ¡ç®ã
cursor.continue();
}
};
ç±äºânameâç´¢å¼ä¸æ¯å¯ä¸ç´¢å¼ï¼å¯è½åºç°å¤ä¸ªæ¡ç® name ç¸åãæ³¨æè¿ç§æ
åµä¸ä¼åçå¨å¯¹è±¡åå¨ä¸ï¼å 为对象åå¨é®å¿
é¡»å¯ä¸ãå¦æä½ å¸æå¨ç´¢å¼æ¸¸æ è¿ä»£æ¶è¿æ»¤éå¤é¡¹ï¼å¯å°æ¹ååæ°è®¾ä¸º nextuniqueï¼ååæ¶ç¨ prevuniqueï¼ãä½¿ç¨ nextunique æ prevunique æ¶ï¼å§ç»è¿åé®å¼æå°çæ¡ç®ã
index.openKeyCursor(null, "nextunique").onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// å¤çæ¡ç®ã
cursor.continue();
}
};
æææ¹ååæ°è¯·åè§âIDBCursor 常éâã
å½ Web åºç¨å¨å¦ä¸ä¸ªæ ç¾é¡µæå¼æ¶åççæ¬åæ´
å½ä½ ç Web åºç¨åçéè¦æ°æ®åºçæ¬åæ´çæ´æ°æ¶ï¼éè¦èèè¿æ ·çåºæ¯ï¼ç¨æ·å¨ä¸ä¸ªæ ç¾é¡µæå¼æ§çåºç¨ï¼åå¨å¦ä¸ä¸ªæ ç¾é¡µå è½½æ°çåºç¨ãè°ç¨ open() ä¸çæ¬å·é«äºå½åæ°æ®åºå®é
çæ¬æ¶ï¼å¿
é¡»çå¾
å
¶ä»å·²æå¼æ°æ®åºæç¡®ç¡®è®¤è¯·æ±ï¼ä½ æè½å¼å§ä¿®æ¹æ°æ®åºï¼å¨å®ä»¬å
³éæéè½½ä¹å伿ç»è§¦å onblocked äºä»¶ï¼ãæµç¨å¦ä¸ï¼
const openReq = mozIndexedDB.open("MyTestDatabase", 2);
openReq.onblocked = (event) => {
// 妿å
¶ä»æ ç¾é¡µå·²æå¼è¯¥æ°æ®åºï¼å¿
é¡»å
å
³éå®ä»¬ï¼æä»¬æè½ç»§ç»ã
console.log("请å
³éæ¬ç½ç«çå
¶ä»æ ç¾é¡µï¼");
};
openReq.onupgradeneeded = (event) => {
// å
¶ä»æ°æ®åºé½å·²å
³éï¼å¼å§è®¾ç½®ã
db.createObjectStore(/* ⦠*/);
useDatabase(db);
};
openReq.onsuccess = (event) => {
const db = event.target.result;
useDatabase(db);
};
function useDatabase(db) {
// ä¸å®è¦æ·»å å¤çå¨ï¼å½å
¶ä»é¡µé¢è¯·æ±çæ¬åæ´æ¶å¯æ¶å°éç¥ãæä»¬å¿
é¡»å
³éæ°æ®åºï¼ä»¥ä¾¿å¦ä¸ä¸ªé¡µé¢å®æå级ãå¦åå级ä¼ä¸ç´å¡ä½ï¼ç´å°ç¨æ·å
³éå½åæ ç¾é¡µã
db.onversionchange = (event) => {
db.close();
console.log("æ¬é¡µé¢çä¸ä¸ªæ°çæ¬å·²å°±ç»ªï¼è¯·å·æ°ç½é¡µä»¥å è½½ï¼");
};
// ä½¿ç¨æ°æ®åºæ§è¡æä½ã
}
ä½ è¿åºçå¬ VersionError é误ï¼ä»¥å¤çè¿ç§æ
åµï¼å·²æå¼åºç¨å¯è½å¨åç»ä»£ç ä¸å次å°è¯æå¼æ°æ®åºï¼ä½ä½¿ç¨çæ¯è¿æ¶çæ¬ã
å®å ¨
IndexedDB 使ç¨åæºååï¼è¿æå³çå®ä¸å建å®çç«ç¹æºç»å®ï¼é常æ¯ç«ç¹ååæåååï¼ï¼å æ¤ä¸è½è¢«å ¶ä»æºè®¿é®ã
妿æµè§å¨è¢«è®¾ç½®ä¸ºä»ä¸æ¥åç¬¬ä¸æ¹ Cookieï¼è§ Firefox bug 1147821ï¼ï¼ç¬¬ä¸æ¹çªå£å
容ï¼ä¾å¦ <iframe> å
容ï¼å°æ æ³è®¿é® IndexedDBã
å ³äºæµè§å¨å ³éçè¦å
彿µè§å¨å ³éï¼ç¨æ·éæ© Quit æ Exitï¼ãæ¿è½½æ°æ®åºçç£çæå¤ç§»é¤ï¼ææ°æ®åºå卿é丢失æ¶ï¼ä¼åç以䏿 åµï¼
- æ¯ä¸ªå影忰æ®åºä¸çæ¯ä¸ªäºå¡ï¼è¥æ¯æµè§å¨å
³éåºæ¯ï¼åä¸ºæææå¼æ°æ®åºï¼é½ä¼ä»¥
AbortError䏿¢ãææçåäºå¯¹æ¯ä¸ªäºå¡è°ç¨IDBTransaction.abort()ã - ææäºå¡å®æåï¼æ°æ®åºè¿æ¥ä¼è¢«å ³éã
- æåï¼è¡¨ç¤ºè¯¥æ°æ®åºè¿æ¥ç
IDBDatabaseå¯¹è±¡ä¼æ¶å°closeäºä»¶ãä½ å¯ä»¥éè¿IDBDatabase.oncloseäºä»¶å¤çå¨çå¬è¿äºäºä»¶ï¼ä»èç¥éæ°æ®åºä½æ¶è¢«æå¤å ³éã
ä¸è¿°è¡ä¸ºæ¯æ°å¢è¡ä¸ºï¼ä» å¨ä»¥ä¸æµè§å¨çæ¬åä¹åå¯ç¨ï¼Firefox 50ãGoogle Chrome 31ï¼å¤§è´ï¼ã
å¨è¿äºçæ¬ä¹åï¼äºå¡ä¼éé»ä¸æ¢ï¼ä¸ä¸ä¼è§¦å close äºä»¶ï¼å æ¤æ æ³æ£æµæ°æ®åºæå¤å
³éã
ç±äºç¨æ·å¯ä»¥éæ¶éåºæµè§å¨ï¼è¿æå³çä½ ä¸è½ä¾èµæä¸ªç¹å®äºå¡ä¸å®å®æï¼å¨æ§æµè§å¨ä¸ï¼çè³ä¸ä¼åè¯ä½ äºå¡æ²¡å®æãè¿ä¼å¸¦æ¥ä¸äºå½±åã
第ä¸ï¼ä½ åºç¡®ä¿æ°æ®åºå¨æ¯æ¬¡äºå¡ç»ææ¶é½ä¿æä¸è´ç¶æãæ¯å¦ä½ ç¨ IndexedDB åä¸ä¸ªå¯ç¼è¾å表ï¼ç¼è¾åéè¿âå æ¸ 空对象åå¨ï¼ååå ¥æ°åè¡¨âæ¥ä¿åãå¦æææ¸ 空ååå ¥æ¾å¨ä¸¤ä¸ªäºå¡ä¸ï¼æµè§å¨å¯è½å¨æ¸ 空åãåå ¥åå ³éï¼å¯¼è´æ°æ®åºè¢«æ¸ 空ãè¦é¿å è¿ç§æ åµï¼åºææ¸ 空ååå ¥æ¾å¨åä¸ä¸ªäºå¡éã
第äºï¼ä¸è¦ææ°æ®åºäºå¡ç»å¨ unload äºä»¶ä¸ã妿 unload ç±æµè§å¨å ³é触åï¼å¨ unload å¤çå¨ä¸å建çäºå¡æ°¸è¿ä¸ä¼å®æãä¸ç§çä¼¼ç´è§çåæ³æ¯ï¼æµè§å¨ï¼æé¡µé¢ï¼æå¼æ¶ä»æ°æ®åºè¯»åä¿¡æ¯ï¼ç¨æ·äº¤äºæ¶æ´æ°ä¿¡æ¯ï¼æµè§å¨ï¼æé¡µé¢ï¼å ³éæ¶åååæ°æ®åºãä½è¿è¡ä¸éãäºå¡ä¼å¨ unload å¤çå¨ä¸å建ï¼ä½ç±äºå ¶å¼æ¥ç¹æ§ï¼ä¼å¨æ§è¡åå°±è¢«ä¸æ¢ã
äºå®ä¸ï¼å³ä½¿æ¯æµè§å¨æ£å¸¸å
³éï¼ä¹æ æ³ä¿è¯ IndexedDB äºå¡ä¸å®å®æãè§ Firefox bug 870645ãä½ä¸ºå¸¸è§å
³ééç¥çæä¸æ¹æ¡ï¼ä½ å¯ä»¥è·è¸ªäºå¡ï¼å¹¶å¨ beforeunload æ¶è¥ä»ææªå®æäºå¡åæç¤ºç¨æ·ã
è³å°å¨å å
¥ä¸æ¢éç¥ä¸ IDBDatabase.onclose åï¼ä½ è½å¤ç¥éè¿ç§æ
åµä½æ¶åçã
宿´ IndexedDB 示ä¾
æä»¬æä¾äºä¸ä¸ªå®æ´ç IndexedDB API 示ä¾ã该示ä¾ä½¿ç¨ IndexedDB åå¨å¹¶æ£ç´¢åºçç©æ°æ®ã
åè§
å¦æä½ å¸æäºè§£æ´å¤ï¼å¯ç»§ç»é 读以ä¸èµæã
åè
- IndexedDB API åè
- Indexed Database API è§è
- Firefox æºç ä¸ç IndexedDB æ¥å£æä»¶
æç¨åæå
åº
- localForageï¼ä¸ºç¨äºå®¢æ·ç«¯æ°æ®å卿ä¾ç®åç name:value è¯æ³çä¸ä¸ª polyfillãå®åºå±ä½¿ç¨ IndexedDBï¼è¥æµè§å¨ä¸æ¯æ IndexedDBï¼ååéå° Web SQLï¼å·²å¼ç¨ï¼ï¼ååéå° localStorageã
- Dexie.jsï¼IndexedDB çå°è£ åºï¼æä¾æ¸ æ°ç®æ´è¯æ³ï¼å¯æ¾èæåå¼åæçã
- JsStoreï¼ä¸ä¸ªç®åä¸é«çº§ç IndexedDB å°è£ ï¼æä¾ç±» SQL è¯æ³ã
- MiniMongoï¼å®¢æ·ç«¯å åç MongoDBï¼ç± localstorage æä¹ åï¼å¹¶éè¿ HTTP 䏿å¡ç«¯åæ¥ãMiniMongo 被 MeteorJS 使ç¨ã
- PouchDBï¼å¨æµè§å¨ä¸åºäº IndexedDB å®ç° CouchDB ç客æ·ç«¯ã
- IDBï¼ä¸ä¸ªå¾å°çåºï¼åºæ¬éå IndexedDB APIï¼åæ¶åäºå°éå¯ç¨æ§æ¹è¿ã
- idb-keyvalï¼ä¸ä¸ªè¶ å°åï¼çº¦ 600Bï¼åºäº Promise çé®å¼åå¨ï¼åºå±å®ç°ä¸º IndexedDBã
- $mol_dbï¼ä¸ä¸ªå¾®åï¼çº¦ 1.3kBï¼TypeScript facadeï¼æä¾ Promise API åèªå¨è¿ç§»ã
- RxDBï¼å¯æå»ºå¨ IndexedDB ä¹ä¸ç NoSQL 客æ·ç«¯æ°æ®åºï¼æ¯æç´¢å¼ãå缩åå¤å¶ï¼å¹¶ä¸º IndexedDB å¢å è·¨æ ç¾é¡µè½åä¸å¯è§å¯æ§ã