InexedDB ã¯çµã¿èŸŒã¿ã®ããŒã¿ããŒã¹ã§ãlocalStorage ãããé¥ãã«åŒ·åã§ãã
- key/value ã¹ãã¬ãŒãž: å€ã¯äœã§ããããè€æ°ã®ããŒã®åããããŸãã
- ä¿¡é Œæ§ã®ããã®ãã©ã³ã¶ã¯ã·ã§ã³ããµããŒãããŸãã
- ããŒç¯å²ã®ã¯ãšãªãã€ã³ããã¯ã¹ããµããŒãããŸãã
localStorageããããã£ãšå€ãã®ããŒã¿ãæ ŒçŽããããšãã§ããŸãã
éåžžããã®æ©èœã¯äŒçµ±çãªã¯ã©ã€ã¢ã³ã-ãµãŒãã¢ããªã±ãŒã·ã§ã³ã«ã¯é倧ã§ããIndexedDB ã¯ãServiceWorkers ãä»ã®ãã¯ãããžãŒãšçµã¿åããããªãã©ã€ã³ã¢ããªã±ãŒã·ã§ã³ãæ³å®ããŠããŸãã
仿§ ã«èšèŒãããŠãã IndexedDB ã®ãã€ãã£ãã€ã³ã¿ãŒãã§ãŒã¹ã¯ãã€ãã³ãããŒã¹ã§ãã
idb ã®ããã«ãpromise ããŒã¹ã®ã©ãããŒã䜿ã£ãŠ async/await ã䜿ãããšãã§ããŸããããã¯éåžžã«äŸ¿å©ã§ãããã©ãããŒã¯å®ç§ã§ã¯ãããŸããããã¹ãŠã®ã±ãŒã¹ã®ã€ãã³ãã眮ãæããããšã¯ã§ããªãã®ã§ãã€ãã³ãããå§ããŠããã®åŸã©ãããŒã䜿çšããŸãããã
ããŒã¿ããŒã¹ãéã
IndexedDB ã䜿ãå§ããã«ã¯ãããŒã¿ããŒã¹ã open ããŸãã
æ§æ:
let openRequest = indexedDB.open(name, version);
nameâ æååãããŒã¿ããŒã¹ã®ååã§ããversionâ æ£ã®æŽæ°ã§è¡šçŸãããããŒãžã§ã³ãããã©ã«ãã¯1(åŸè¿°).
ç§ãã¡ã¯ãç°ãªãååã§å€ãã®ããŒã¿ããŒã¹ãæã€ããšãã§ãããããã¯ãã¹ãŠçŸåšã®ãªãªãžã³ (domain/protocol/port) ã®äžã«ãããŸãããã®ãããå¥ã®Webãµã€ãã¯äºãã®ããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããããšã¯ã§ããŸããã
åŒã³åºãåŸãopenRequest ãªããžã§ã¯ãã®ã€ãã³ãããªãã¹ã³ããå¿
èŠããããŸãã:
success: ããŒã¿ããŒã¹ã®æºåãã§ããŸããã以éã®åŠçã§ã¯ããŒã¿ããŒã¹ãªããžã§ã¯ãopenRequest.resultã䜿ããŸããerror: éãã®ã«å€±æããŸãããupgradeneeded: ããŒã¿ããŒã¹ã®ããŒãžã§ã³ãå€ããªã£ãŠããŸã(äžãèŠãŠãã ãã)ã
IndexedDB ã«ã¯ããµãŒããµã€ãã®ããŒã¿ããŒã¹ã«ã¯ãªããçµã¿èŸŒã¿ã® âã¹ããŒãããŒãžã§ãã³ã°â ã®ä»çµã¿ããããŸãã
ãµãŒããµã€ãã®ããŒã¿ããŒã¹ãšã¯ç°ãªããIndexedDB ã¯ã¯ã©ã€ã¢ã³ããµã€ãã§ããããŒã¿ã¯æå ã«ã¯ãããŸãããããããæ°ããã¢ããªãå ¬éãããšããããŒã¿ããŒã¹ã®æŽæ°ãå¿ èŠãªããšããããŸãã
ããŒã«ã«ããŒã¿ããŒã¹ããŒãžã§ã³ã open ã§æå®ããããã®ããå°ããå Žåãç¹å¥ãªã€ãã³ã upgradeneeded ãããªã¬ãŒãããå¿
èŠã«å¿ããŠããŒãžã§ã³ãæ¯èŒããããŒã¿æ§é ãæŽæ°ããäºãã§ããŸãã
ãã®ã€ãã³ãã¯ããŒã¿ããŒã¹ããŸã ååšããªãã£ãå Žåã«ãèµ·ããã®ã§ãåæåã®å®è¡ãããããšãã§ããŸãã
äŸãã°ãæåã«ã¢ããªãå
¬éãããšãã«ã¯ãããŒãžã§ã³ 1 ã§ open ããupgradeneeded ãã³ãã©ã§åæåãå®è¡ããŸãã:
let openRequest = indexedDB.open("store", 1);
openRequest.onupgradeneeded = function() {
// ã¯ã©ã€ã¢ã³ããããŒã¿ããŒã¹ãæã£ãŠããªãå Žåã«ããªã¬ãŒãããŸã
// ...åæåãè¡ããŸã...
};
openRequest.onerror = function() {
console.error("Error", openResult.error);
};â
openRequest.onsuccess = function() {
let db = openRequest.result;
// db ãªããžã§ã¯ãã仿§ããŠããŒã¿ããŒã¹ãæäœããŸã
};
次ã®ããŒãžã§ã³ããªãªãŒã¹ããæ:
let openRequest = indexedDB.open("store", 2);
// æ¢åã®ããŒã¿ããŒã¹ã®ããŒãžã§ã³ããã§ãã¯ããå¿
èŠãªãæŽæ°ãã:
openRequest.onupgradeneeded = function() {
let db = openRequest.result;
switch(db.version) { // æ¢åã® (å€ã) db ã®ããŒãžã§ã³
case 0:
// ããŒãžã§ã³ 0 ã¯ãã¯ã©ã€ã¢ã³ããããŒã¿ããŒã¹ãæã£ãŠããªãããšãæå³ããŸã
// åæåãè¡ããŸã
case 1:
// ã¯ã©ã€ã¢ã³ãã¯ããŒãžã§ã³ 1
// ææ°çã«æŽæ°ããŸã
}
};
openRequest.onsuccess ã®åŸãããŒã¿ããŒã¹ãªããžã§ã¯ã㯠openRequest.result ã«ãããŸãã以éã®æäœã§ããã䜿ã£ãŠãããŸãã
ããŒã¿ããŒã¹ãåé€ããã«ã¯:
let deleteRequest = indexedDB.deleteDatabase(name)
// deleteRequest.onsuccess/onerror ã§çµæã远跡ããŸã
ãªããžã§ã¯ãã¹ãã¢
ãªããžã§ã¯ãã¹ãã¢ã¯ IndexedDB ã®äžå¿ãšãªãæŠå¿µã§ããä»ã®ããŒã¿ããŒã¹ã§ã¯ âããŒãã«â ã âã³ã¬ã¯ã·ã§ã³â ãšåŒã°ããŠãããã®ã§ããããã¯ããŒã¿ãæ ŒçŽãããå Žæã§ããããŒã¿ããŒã¹ã¯è€æ°ã®ã¹ãã¢ãæã€ããšããããŸãã: 1ã€ã¯ãŠãŒã¶çšãããïŒã€ã¯ååçšããªã©ã§ãã
âãªããžã§ã¯ãã¹ãã¢â ãšããååã§ã¯ãããŸãããããªããã£ããæ ŒçŽããããšãå¯èœã§ãã
è€éãªãªããžã§ã¯ãå«ããã»ãŒã©ããªå€ã§ãæ ŒçŽããããšãã§ããŸãã
IndexedDB 㯠standard serialization algorithm ã䜿çšããŠãªããžã§ã¯ããè€è£œãæ ŒçŽããŸãããã㯠JSON.stringify ã«äŒŒãŠããŸããããã匷åã§é¥ãã«å€ãã®ããŒã¿ã¿ã€ããæ ŒçŽããããšãã§ããŸãã
æ ŒçŽã§ããªããªããžã§ã¯ãã®äŸã¯ã埪ç°åç
§ãæã€ãªããžã§ã¯ãã§ãããã®ãããªãªããžã§ã¯ãã¯ã·ãªã¢ã©ã€ãºå¯èœã§ã¯ãããŸãããJSON.stringify ã倱æããŸãã
ã¹ãã¢å
ã®ãã¹ãŠã®å€ã«ã¯äžæãšãªã key ãå¿
èŠã§ãã
ããŒã¯æ¬¡ã®ããããã®ã¿ã€ãã§ãªããã°ãªããŸãã: number, date, string, binary, ãŸã㯠arrayãããã¯äžæãªãªããžã§ã¯ãèå¥åã§ãããŒã䜿ã£ãŠå€ã®æ€çŽ¢/åé€/æŽæ°ãããããšãã§ããŸãã
localStorage ãšåæ§ãã¹ãã¢ã«å€ã远å ãããšãã«ããŒãæå®ã§ããŸããããã¯ããªããã£ãå€ãæ ŒçŽããã®ã«é©ããŠããŸãã ãããããªããžã§ã¯ããæ ŒçŽãããšããIndexedDB ã¯ãªããžã§ã¯ãããããã£ãããŒãšããŠèšå®ããããšãå¯èœã«ããããã¯ãšãŠã䟿å©ã§ãããããã¯ãããŒãèªåçæããããšãã§ããŸãã
ãªããžã§ã¯ãã¹ãã¢ãäœæããæ§æ:
db.createObjectStore(name[, keyOptions]);
æäœã¯åæã§ãããawait ã¯å¿
èŠãªãããšã«çæããŠãã ããã
nameã¯ã¹ãã¢åã§ããe.g. æ¬çšã«"books"ãªã©keyOptionsã¯2ã€ã®ããããã£ã®ãã¡1ã€ãæã€ãªãã·ã§ã³ã®ãªããžã§ã¯ãã§ããkeyPathâ IndexedDBãããŒãããŠäœ¿çšãããªããžã§ã¯ãããããã£ã®ãã¹ã§ããe.g. `id.autoIncrementâtrueã®å Žåãæ°ããæ ŒçŽããããªããžã§ã¯ãã®ããŒã¯ãã€ã³ã¯ãªã¡ã³ããããæ°å€ãšããŠãèªåçã«çæãããŸãã
äœããªãã·ã§ã³ãæå®ããªãå Žåã¯ãããšã§ãªããžã§ã¯ããæ ŒçŽãããšãã«æç€ºçã«ããŒãæå®ããå¿ èŠããããŸãã
äŸãã°ããã®ãªããžã§ã¯ãã¹ãã¢ã¯ããŒãšã㊠id ããããã£ã䜿çšããŸãã:
db.createObjectStore('books', {keyPath: 'id'});
ãªããžã§ã¯ãã¹ãã¢ã¯ upgradeneeded ãã³ãã©å
ã§ DB ããŒãžã§ã³ãæŽæ°ããŠããéã«ã ããçæ/倿Žããããšãã§ããŸãã
ããã¯æè¡çãªå¶éã«ãããã®ã§ãããã³ãã©ã®å€åŽã§ã¯ããŒã¿ã®è¿œå /åé€/æŽæ°ãå¯èœã§ããããªããžã§ã¯ãã¹ãã¢ã®å€æŽã¯ããŒãžã§ã³ã®æŽæ°äžã ãã§ãã
ã¢ããã°ã¬ãŒãããæ¹æ³ã¯ãäž»ã«2ã€ãããŸã:
- ããŒãžã§ã³ãæ¯èŒããããŒãžã§ã³ããšã®æäœãè¡ããŸãã
- ãããã¯ã
db.objectStoreNamesã§æ¢åã®ãªããžã§ã¯ãã¹ãã¢ã®äžèЧãååŸã§ããŸãããã®ãªããžã§ã¯ã㯠DOMStringList ã§ãããååšãã§ãã¯ã®ããã®ã¡ãœããcontains(name)ãæäŸããŸãããããŠååšãããã®ã«å¿ããŠæŽæ°ãè¡ããŸãã
ããã¯ïŒã€ç®ã®ã¢ãããŒãã®å Žåã®ãã¢ã§ã:
let openRequest = indexedDB.open("db", 1);
// ååšããªãå Žåã«ã¯ books ã®ããã®ãªããžã§ã¯ãã¹ãã¢ãäœæãã
openRequest.onupgradeneeded = function() {
let db = openRequest.result;
if (!db.objectStoreNames.contains('books')) {
db.createObjectStore('books', {keyPath: 'id'});
}
};
ãªããžã§ã¯ãã¹ãã¢ãåé€ããã«ã¯:
db.deleteObjectStore('books')
ãã©ã³ã¶ã¯ã·ã§ã³
âãã©ã³ã¶ã¯ã·ã§ã³â ãšããçšèªã¯äžè¬çã§ãå€ãã®ããŒã¿ããŒã¹ã§äœ¿ãããŠããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³ã¯ã°ã«ãŒãæäœã§ããããã¹ãŠæåããã/ãã¹ãŠå€±æãããã®ããããã«ãªããŸãã
äŸãã°ããã人ãäœããè³Œå ¥ãããšããæ¬¡ã®ããšãå¿ èŠã§ãã:
- å£åº§ãããéãåŒãèœãšããŸãã
- è³Œå ¥è ã®æã¡ç©ã«è³Œå ¥ããååã远å ããŸãã
ãããᅵᅵᅵåã®åŠçãå®äºãããã®åŸãäŸãã°åé»ãªã©ã§äžæãåŠçã§ããæ¬¡ã®åŠçã倱æãããšãéåžžã«ãŸããã§ããããã©ã¡ããæåãã(è³Œå ¥å®äº)ãããã¯å€±æãã(å°ãªããšãè³Œå ¥è ã¯ãéã¯åŒãããŠãããããªãã©ã€ã§ãã)ã¹ãã§ãã
ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãããä¿èšŒããŸãã
IndexedDB ã§ã®ãã¹ãŠã®ããŒã¿æäœã¯ãã©ã³ã¶ã¯ã·ã§ã³å ã§è¡ããªããã°ãªããŸããã
ãã©ã³ã¶ã¯ã·ã§ã³ãéå§ããã«ã¯:
db.transaction(store[, type]);
storeã¯ãã©ã³ã¶ã¯ã·ã§ã³ãã¢ã¯ã»ã¹ããã¹ãã¢åã§ããe.g."books"ãè€æ°ã®ã¹ãã¢ã«ã¢ã¯ã»ã¹ããå Žåã¯ãã¹ãã¢åã®é åãæå®ããŸããtypeã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®ã¿ã€ãã§ãã以äžã®ããããã§ã:readonly: åç §ã®ã¿ãããã©ã«ãã§ããreadwrite: èªã¿æžãå¯èœã§ããããªããžã§ã¯ãã¹ãã¢ã®å€æŽã¯ã§ããŸããã
versionchange ãšãããã©ã³ã¶ã¯ã·ã§ã³ã¿ã€ãããããŸãã: ãã®ãããªãã©ã³ã¶ã¯ã·ã§ã³ã¯äœã§ãã§ããŸãããæåã§äœãããšã¯ã§ããŸãããIndexedDBã¯ãupdateneeded ãã³ãã©ã®å ŽåãããŒã¿ããŒï¿œï¿œï¿œãéããšãã« versionchange ãã©ã³ã¶ã¯ã·ã§ã³ãèªåçã«äœæããŸãããã®ããããããããŒã¿ããŒã¹æ§é ã®æŽæ°ããªããžã§ã¯ãã¹ãã¢ã®äœæ/åé€ãå¯èœãªå¯äžã®å Žæã«ãªããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³ã readonly ã readwrite ã®ããããã«ã©ãã«ä»ããããå¿
èŠãããã®ã¯ãããã©ãŒãã³ã¹ãçç±ã§ãã
å€ãã® readonly ãã©ã³ã¶ã¯ã·ã§ã³ã¯åãã¹ãã¢ã«åæã«ã¢ã¯ã»ã¹å¯èœã§ãããreadwrite ãã©ã³ã¶ã¯ã·ã§ã³ã¯ã§ããŸãããreadwrite ãã©ã³ã¶ã¯ã·ã§ã³ã¯æžã蟌ã¿ã®ããã«ã¹ãã¢ã âããã¯â ããŸããæ¬¡ã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãåãã¹ãã¢ã«ã¢ã¯ã»ã¹ããåã«ãŸãã®ãã©ã³ã¶ã¯ã·ã§ã³ãçµäºãããŸã§åŸ
ããªããã°ãªããŸããã
ãã©ã³ã¶ã¯ã·ã§ã³ãäœæãããããæ¬¡ã®ããã«ããŠã¹ãã¢ã«ã¢ã€ãã ã远å ããããšãã§ããŸã:
let transaction = db.transaction("books", "readwrite"); // (1)
// æäœããããã«ãªããžã§ã¯ãã¹ãã¢ãååŸ
let books = transaction.objectStore("books"); // (2)
let book = {
id: 'js',
price: 10,
created: new Date()
};
let request = books.add(book); // (3)
request.onsuccess = function() { // (4)
console.log("Book added to the store", request.result);
};
request.onerror = function() {
console.log("Error", request.error);
};
åºæ¬çã«4ã€ã®ã¹ãããããããŸãã:
- ãã©ã³ã¶ã¯ã·ã§ã³ãäœæãã
(1)ã§ã¢ã¯ã»ã¹ããããšããŠãããã¹ãŠã®ã¹ãã¢ã«ã€ããŠèšåããŸãã (2)ã§transaction.objectStoreïŒnameïŒã䜿ã£ãŠã¹ãã¢ãªããžã§ã¯ããååŸããŸãã(3)ã§ãªããžã§ã¯ãã¹ãã¢ã«ãªã¯ãšã¹ããå®è¡ããŸã:books.add(book)ã- âŠ
(4)ã§ãªã¯ãšã¹ãã®æå/ãšã©ãŒ ãåŠçããå¿ èŠã«å¿ããŠä»ã®ãªã¯ãšã¹ããããããªã©ã
ãªããžã§ã¯ãã¹ãã¢ã¯å€ãæ ŒçŽããããã®2ã€ã®ã¡ãœããããµããŒãããŠããŸãã:
-
put(value, [key]) ã¹ãã¢ã«
valueã远å ããŸããkeyã¯ããªããžã§ã¯ãã¹ãã¢ãkeyPathãautoIncrementãªãã·ã§ã³ãæã£ãŠããªãã£ãå Žåã«ã®ã¿æäŸãããŸããããåãããŒããã€å€ããã§ã«ååšããŠããå Žåã«ã¯ãå€ã¯çœ®ãæããããŸãã -
add(value, [key])
putãšåãã§ãããåãããŒãæã€å€ããã§ã«ååšããå Žåããªã¯ãšã¹ãã¯å€±æãã"ConstraintError"ãšããååã®ãšã©ãŒãçæãããŸãã
ããŒã¿ããŒã¹ãéããšããšåãããã«ããªã¯ãšã¹ããéä¿¡(books.add(book))ããsuccess/error ã€ãã³ãããŸã¡ãŸãã
addã®å Žåã®request.resultã¯æ°ãããªããžã§ã¯ãã®ããŒã§ãã- ãšã©ãŒã¯
request.errorã«ãããŸã(ããã°)ã
ãã©ã³ã¶ã¯ã·ã§ã³ã®èªåã³ããã
äžã®äŸã§ã¯ããã©ã³ã¶ã¯ã·ã§ã³ãéå§ããŠãadd ãªã¯ãšã¹ããè¡ããŸããããåã«è¿°ã¹ãããã«ããã©ã³ã¶ã¯ã·ã§ã³ã«ã¯è€æ°ã®ãªã¯ãšã¹ããé¢é£ä»ããããšãå¯èœã§ãããããŠãããã¯ãã¹ãŠæåã倱æãã®ã©ã¡ããã§ãªããšãããŸããããã©ã³ã¶ã¯ã·ã§ã³ãçµäºãšããŠããŒã¯ããïŒãã以äžãªã¯ãšã¹ãããªãïŒã«ã¯ã©ã®ããã«ãããããã§ããããã
äžèšã§èšããš: ãã®ãããªããšã¯ããŸããã
仿§ã®æ¬¡ã®ããŒãžã§ã³ 3.0 ã§ã¯ããããããã©ã³ã¶ã¯ã·ã§ã³ãæåã§çµäºãããæ¹æ³ãããã§ãããããä»ã®ãšããã2.0 ã«ã¯ãããŸããã
ãã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ã®èŠæ±ãçµäºããmicrotasks queue ã空ã«ãªããšãèªåçã«ã³ããããããŸãã
éåžžããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã¹ãŠã®ãªã¯ãšã¹ããå®äºããçŸåšã®ã³ãŒããçµäºãããšãã«ã³ããããããšæ³å®ï¿œï¿œããŸãã
ãªã®ã§ãäžã®äŸã§ã¯ãã©ã³ã¶ã¯ã·ã§ã³ãçµäºãããããã®ç¹å¥ãªåŒã³åºãã¯å¿ èŠãããŸããã
ãã©ã³ã¶ã¯ã·ã§ã³èªåã³ãããã®ååã«ã¯éèŠãªå¯äœçšããããŸãããã©ã³ã¶ã¯ã·ã§ã³ã®éäžã§ fetch, setTimeout ãšãã£ãéåææäœãæ¿å
¥ããããšãã§ããŸãããIndexedDB ã¯ããããçµãããŸã§ãã©ã³ã¶ã¯ã·ã§ã³ãåŸ
æ©ãããŸããã
以äžã®ã³ãŒãã§ã¯ãè¡ (*) ã® request2 ã¯å€±æããŸãããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã§ã«ã³ããããããŠãããããã§ã¯ã©ããªãªã¯ãšã¹ããè¡ãããšãã§ããªãããã§ã:
let request1 = books.add(book);
request1.onsuccess = function() {
fetch('/').then(response => {
let request2 = books.add(anotherBook); // (*)
request2.onerror = function() {
console.log(request2.error.name); // TransactionInactiveError
};
});
};
ãã㯠fetch ãéåææäœãmacrotask ã§ããããã§ãããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã©ãŠã¶ã macrotask ã®å®è¡ãéå§ããåã«ã¯ããŒãºãããŸãã
IndexedDB 仿§ã®äœæè ã¯ããã©ã³ã¶ã¯ã·ã§ã³ã¯çåœã§ããã¹ãã ãšèããŠããŸããäž»ã«ããã©ãŒãã³ã¹äžã®çç±ããã§ãã
ç¹ã«ãreadwrite ãã©ã³ã¶ã¯ã·ã§ã³ã¯æžã蟌ã¿ã®ããã«ã¹ãã¢ã âããã¯â ããŸãããããã£ãŠãã¢ããªã±ãŒã·ã§ã³ã®äžéšã books ãªããžã§ã¯ãã¹ãã¢äžã§ readwrite ãéå§ããå Žåãåãããšããããã£ãã¢ããªã±ãŒã·ã§ã³ã®å¥ã®éšåã¯åŸ
æ©ããªããã°ãªããŸãããæ°ããªãã©ã³ã¶ã¯ã·ã§ã³ã¯ãæåã®ãã©ã³ã¶ã¯ã·ã§ã³ãçµäºãããŸã§ âãã³ã°â ããŸãã ãã©ã³ã¶ã¯ã·ã§ã³ã«æéãããããšãå¥åŠãªé
å»¶ã«ã€ãªããå¯èœæ§ããããŸãã
ã§ã¯äœãããã°ããã§ããããïŒ
äžã®äŸã§ã¯ãæ°ããªãªã¯ãšã¹ã (*) ã®çŽåã«æ°ãã db.transaction ãäœæããããšãã§ããŸãã
ã§ãããïŒã€ã®ãã©ã³ã¶ã¯ã·ã§ã³å ã§æäœããŸãšãããå Žåã«ã¯ãIndexedDB ãã©ã³ã¶ã¯ã·ã§ã³éšåãš âãã®ä»â ã®éåæéšåã«åå²ããã®ãããã«è¯ãæ¹æ³ã§ãããã
ãŸããfetch ãããŠå¿
èŠã«å¿ããŠããŒã¿ãæºåããŸãããã®åŸããã©ã³ã¶ã¯ã·ã§ã³ãäœæããã¹ãŠã®ããŒã¿ããŒã¹ãªã¯ãšã¹ããå®è¡ãããšãããŸãæ©èœããŸãã
æ£åžžã«å®äºããç¬éãæ€ç¥ããã«ã¯ãtransaction.oncomplete ã€ãã³ãããªãã¹ã³ããŸã:
let transaction = db.transaction("books", "readwrite");
// ...æäœãå®è¡ããŸã...
transaction.oncomplete = function() {
console.log("Transaction is complete");
};
complete ã ãããã©ã³ã¶ã¯ã·ã§ã³å
šäœãä¿åãããããšãä¿èšŒããŸããåã
ã®ãªã¯ãšã¹ãã¯æåãããããããŸããããæçµçãªæžãèŸŒã¿æäœã¯å€±æããå¯èœæ§ããããŸãïŒäŸ. I/O ãšã©ãŒãªã©ïŒ
ãã©ã³ã¶ã¯ã·ã§ã³ãæåã§åæ¢ããã«ã¯ã以äžãåŒã³åºããŸã:
transaction.abort();
ããã«ããããã®äžã®ãªã¯ãšã¹ãã«ããè¡ããããã¹ãŠã®å€æŽããã£ã³ã»ã«ããtransaction.onabort ã€ãã³ããããªã¬ãŒããŸãã
ãšã©ãŒãã³ããªã³ã°
æžã蟌ã¿ãªã¯ãšã¹ãã¯å€±æããå¯èœæ§ããããŸãã
ããã¯ãããããåŽã§çºçããããšã©ãŒã ãã§ãªãããã©ã³ã¶ã¯ã·ã§ã³èªäœãšã¯é¢é£ããªãçç±ããçºçããããšãäºæ³ãããŸããäŸãã°ãã¹ãã¬ãŒãžå®¹éãè¶ ããå Žåã§ãããã®ããããã®ãããªã±ãŒã¹ãåŠçããæºåãã§ããŠããå¿ èŠããããŸãã
ãªã¯ãšã¹ãã倱æãããšããã©ã³ã¶ã¯ã·ã§ã³ã¯èªåçã«äžæ¢ããããã¹ãŠã®å€æŽããã£ã³ã»ã«ãããŸãã
ã±ãŒã¹ã«ãã£ãŠã¯ãæ¢åã®å€æŽããã£ã³ã»ã«ããã«å€±æãåŠçïŒäŸãã°å¥ã®ãªã¯ãšã¹ãã詊ã¿ãïŒãããã©ã³ã¶ã¯ã·ã§ã³ãç¶ç¶ãããããšããããŸããããã¯å¯èœã§ããrequest.onerror ãã³ãã©ã§ã¯ãevent.preventDefault() åŒã³åºããããããšã§ããã©ã³ã¶ã¯ã·ã§ã³ãäžæ¢ããªãããã«ããããšãã§ããŸãã
以äžã®äŸã¯ããã§ã«ååšããããŒãšåãããŒïŒidïŒã§æ°ããæ¬ã远å ãããŠããŸãããã®å Žåãstore.add ã¡ãœãã㯠"ConstraintError" ãçæããŸãããã®äŸã§ã¯ãã©ã³ã¶ã¯ã·ã§ã³ããã£ã³ã»ã«ããã«åŠçããŠããŸãã:
let transaction = db.transaction("books", "readwrite");
let book = { id: 'js', price: 10 };
let request = transaction.objectStore("books").add(book);
request.onerror = function(event) {
// åã id ã®ãªããžã§ã¯ããæ¢ã«ååšããå ŽåãConstraintError ãᅵᅵᅵçããŸã
if (request.error.name == "ConstraintError") {
console.log("Book with such id already exists"); // ãšã©ãŒåŠç
event.preventDefault(); // ãã©ã³ã¶ã¯ã·ã§ã³ãäžæ¢ããŸãã
// å¥ã®ããŒãå©çšããïŒãªã©
} else {
// unexpected error
// åŠçã§ããªãã®ã§ããã©ã³ã¶ã¯ã·ã§ã³ã¯äžæ¢ããŸã
}
};
transaction.onabort = function() {
console.log("Error", transaction.error);
};
ã€ãã³ãå§è²ïŒdelegationïŒ
ãã¹ãŠã®ãªã¯ãšã¹ãã«å¯Ÿã㊠onerror/onsuccess ãå¿ èŠã§ããããïŒæ¯åã§ã¯ãããŸãããã®ã§ã代ããã«ã€ãã³ãå§è²ãå©çšã§ããŸãã
IndexedDB ã®ã€ãã³ãããã«: request â transaction â database.
ãã¹ãŠã®ã€ãã³ã㯠ãã£ããã£ãªã³ã°ãšãããªã³ã°ãæã€ DOM ã€ãã³ãã§ãéåžžã¯ãããªã³ã°ã¹ããŒãžã ããå©çšãããŸãã
ãããã£ãŠãã¬ããŒããä»ã®ç®çã®ããã« db.onerror ãã³ãã©ã䜿çšããŠãã¹ãŠã®ãšã©ãŒããã£ããããããšãå¯èœã§ãã
db.onerror = function(event) {
let request = event.target; // ãšã©ãŒãçºçãããªã¯ãšã¹ã
console.log("Error", request.error);
};
âŠã§ãããä»®ã«ãšã©ãŒãå®å
šã«åŠçããããïŒãã®å Žåã¯ã¬ããŒããããã¯ãããŸããã
request.onerror ã§ event.stopPropagation() ãå©çšããããšã§ãããªã³ã°ãã€ãŸã db.onerror ã忢ããããšãã§ããŸãã
request.onerror = function(event) {
if (request.error.name == "ConstraintError") {
console.log("Book with such id already exists"); // ãšã©ãŒåŠç
event.preventDefault(); // ãã©ã³ã¶ã¯ã·ã§ã³ãäžæ¢ããããªã
event.stopPropagation(); // ãšã©ãŒãããã«ããŸãããããèããŠãã ãã
} else {
// äœãããŸãã
// ãã©ã³ã¶ã¯ã·ã§ã³ã¯äžæ¢ãããŸã
// transaction.onabort ã§ãšã©ãŒãæ±ãããšãã§ããŸã
}
};
ããŒã§æ€çŽ¢ãã
ãªããžã§ã¯ãã¹ãã¢ã®æ€çŽ¢ã«ã¯äž»ã«ïŒã€ã®çš®é¡ããããŸãã:
- ã㌠or ããŒç¯å²ã«ãããã®ãã€ãŸããâbooksâ ã¹ãã¬ãŒãžã§ã¯
book.idã§ãã - å¥ã®ãªããžã§ã¯ããã£ãŒã«ãã«ãããã®ãäŸãã°ã
book.priceã
æåã«ãããŒãšããŒç¯å² (1) ãåãæ±ããŸãããã
æ€çŽ¢ã䌎ãã¡ãœããã¯ãæ£ç¢ºãªã㌠ãããã¯ãããã âç¯å²ã¯ãšãªâïŒâããŒç¯å²â ãæå®ãã IDBKeyRangeãªããžã§ã¯ãïŒ ã®ããããããµããŒãããŸãã
ç¯å²ã¯æ¬¡ã®åŒã³åºãã䜿çšããŠçæãããŸã:
IDBKeyRange.lowerBound(lower, [open])æå³:â¥lower(openã true ãªã>lower)IDBKeyRange.upperBound(upper, [open])æå³:â€upper(openã true ãªã<upper)IDBKeyRange.bound(lower, upper, [lowerOpen], [upperOpen])æå³:lowerãšupperã®é. open ãã©ã°ã true ã®å Žåã察å¿ããããŒã¯ç¯å²ã«å«ãŸããŸãããIDBKeyRange.only(key)â åäžã®keyã®ã¿ã§æ§æãããç¯å²ã§ããã£ãã«äœ¿ãããŸããã
ãã¹ãŠã®æ€çŽ¢ã¡ãœããã¯æ£ç¢ºãªããŒãŸãã¯ããŒç¯å²ã®ããããã® query åŒæ°ãåãä»ããŸãã:
store.get(query)â ã㌠or ç¯å²ã§ãæåã®å€ãæ€çŽ¢ããŸããstore.getAll([query], [count])â ãã¹ãŠã®å€ãæ€çŽ¢ããŸããcountãæå®ãããŠããå Žåã¯ãã®æ°ã§å¶éãᅵᅵᅵãŸããstore.getKey(query)â ã¯ãšãªãæºããæåã®ããŒãæ€çŽ¢ããŸããéåžžã¯ç¯å²ã§ããstore.getAllKeys([query], [count])â ã¯ãšãªãæºãããã¹ãŠã®ããŒãæ€çŽ¢ããŸããéåžžã¯ç¯å²ã§ãcountãæå®ãããŠããå Žåã¯ãã®æ°ãŸã§ã§ããstore.count([query])â ã¯ãšãªãæºããããŒã®ç·æ°ãååŸããŸïœïŒéåžžã¯ç¯å²ã§ãã
äŸãã°ãã¹ãã¢ã«å€§éã®æ¬(books)ããããšããŸããid ãã£ãŒã«ãã¯ããŒãªã®ã§ãããããã¹ãŠã®ã¡ãœãã㯠id ã§æ€çŽ¢ãã§ããããšãå¿ããªãã§ãã ããã
ãªã¯ãšã¹ãäŸ:
// åäžã®æ¬ãååŸ
books.get('js')
// 'css' <= id <= 'html' ã®æ¬ãååŸ
books.getAll(IDBKeyRange.bound('css', 'html'))
// id < 'html' ã®æ¬ãååŸ
books.getAll(IDBKeyRange.upperBound('html', true))
// ãã¹ãŠã®æ¬ãååŸ
books.getAll()
// id > 'js' ã®ãã¹ãŠã®ããŒãååŸ
books.getAllKeys(IDBKeyRange.lowerBound('js', true))
ãªããžã§ã¯ãã¹ãã¢ã¯å éšçã«ãããŒã«ããå€ããœãŒãããŠããŸãã
ãã®ãããå€ãã®å€ãè¿ããªã¯ãšã¹ãã¯ãåžžã«ããŒé ã«ãœãŒããããçµæãè¿ããŸãã
index ä»ãã®ä»»æã®ãã£ãŒã«ãã§æ€çŽ¢ãã
ä»ã®ãªããžã§ã¯ããã£ãŒã«ãã§æ€çŽ¢ããã«ã¯ãâindexâ ãšåŒã°ãã远å ã®ããŒã¿æ§é ãçæããå¿ èŠããããŸãã
index ã¯ç¹å®ã®ãªããžã§ã¯ããã£ãŒã«ãã远跡ããã¹ãã¢ãžã® âã¢ããªã³â ã§ãããã®ãã£ãŒã«ãã®å€ããšã«ããã®å€ãæã€ãªããžã§ã¯ãã®ããŒã®ãªã¹ããæ ŒçŽããŸãã以äžã«ãã詳现ãªå³ããããŸãã
æ§æ:
objectStore.createIndex(name, keyPath, [options]);
nameâ index å,keyPathâ index ã远跡ãã¹ããªããžã§ã¯ããã£ãŒã«ãã®ãã¹ïŒå°æ¥ãã®ãã£ãŒã«ãã§æ€çŽ¢ããŸãïŒoptionâ æ¬¡ã®ããããã£ããã€ãªãã·ã§ã³ã®ãªããžã§ã¯ã:uniqueâ true ã®å Žåãã¹ãã¢ã«ã¯keyPathã§æå®ãããå€ããã€ãªããžã§ã¯ãã1ã€ãããªãããšã瀺ããŸããéè€ã远å ããããšããå Žåãindex ã¯ãšã©ãŒãçæããããšã§ããã匷å¶ããŸããmultiEntryâkeyPathã®å€ãé åã®å Žåã«ã®ã¿äœ¿ãããŸãããã®å Žåãããã©ã«ãã§ã¯ index ã¯é åå šäœãããŒãšããŠæ±ããŸãããmultiEntryã true ã®å Žåã¯ãindex ã¯é åå ã®åå€ã®ã¹ãã¢ãªããžã§ã¯ãã®ãªã¹ããç¶æããŸãããããã£ãŠãé åèŠçŽ ã¯ index ããŒã«ãªããŸãã
ããããã®äŸã§ã¯ãid ã§ããŒèšå®ãããæ¬ãæ ŒçŽããŠããŸãã
ããã§ãprice ã§æ€çŽ¢ããããšããŸãããã
ãŸããindex ãäœæããå¿
èŠããããŸãããªããžã§ã¯ãã¹ãã¢åæ§ãupgradeneeded ã§è¡ããªããã°ãªããŸããã:
openRequest.onupgradeneeded = function() {
// index ã¯ãããããŒãžã§ã³å€æŽã®ãã©ã³ã¶ã¯ã·ã§ã³ã®äžã§äœæããå¿
èŠããããŸã
let books = db.createObjectStore('books', {keyPath: 'id'});
let index = books.createIndex('price_idx', 'price');
};
- index ã¯
priceãã£ãŒã«ãã远跡ããŸãã - priceïŒäŸ¡æ ŒïŒã¯ãŠããŒã¯ã§ã¯ãªãã®ã§ãåãäŸ¡æ Œã§è€æ°ã®æ¬ãååšããå¯èœæ§ããããŸãããã®ããã
uniqueãªãã·ã§ã³ã¯èšå®ããŸããã - priceïŒäŸ¡æ ŒïŒã¯é
åã§ã¯ãªãã®ã§ã
multiEntryãã©ã°ã¯é©çšãããŸããã
inventory ã«4åã®æ¬ããããšããŸãããã㯠index ãäœã§ããããæ£ç¢ºã«ç€ºãå³ã§ã:
æ¢ã«è¿°ã¹ãéããprice ïŒ2ã€ç®ã®åŒæ°ïŒã®åå€ã® index ã¯ããã® äŸ¡æ Œ ããã€ããŒã®äžèЧãä¿æããŸãã
index ã¯èªåã§ææ°ç¶æ ãç¶æãããã®ã§ãæ°ã«ããå¿ èŠã¯æããŸããã
ããŸãç¹å®ã®äŸ¡æ Œã§æ€çŽ¢ããããå Žåãåã« index ã«å¯ŸããŠåãæ€çŽ¢ã¡ãœãããé©çšããã ãã§ãã:
let transaction = db.transaction("books"); // readonly
let books = transaction.objectStore("books");
let priceIndex = books.index("price_idx");
let request = priceIndex.getAll(10);
request.onsuccess = function() {
if (request.result !== undefined) {
console.log("Books", request.result); // price=10 ã®æ¬ã®é
å
} else {
console.log("No such books");
}
};
IDBKeyRange ã§ç¯å²ãäœæããå®ã/é«ãæ¬ãæ¢ãããšãã§ããŸã:
// price <= 5 ã®æ¬ãèŠã€ãã
let request = priceIndex.getAll(IDBKeyRange.upperBound(5));
index ã¯å
éšçã«ã¯è¿œè·¡ãããŠãããªããžã§ã¯ããã£ãŒã«ãïŒãã®ã±ãŒã¹ã§ã¯ priceïŒã§ãœãŒããããŠããŸãããªã®ã§ãæ€çŽ¢ãããšããçµæããŸã price ã§ãœãŒããããŠããŸãã
ã¹ãã¢ããåé€ãã
delete ã¡ãœããã¯ã¯ãšãªã«ãã£ãŠåé€ããå€ã調ã¹ãŸããåŒã³åºã圢åŒã¯ getAll ãšåãã§ã:
delete(query)â ã¯ãšãªã«ãããããå€ãåé€ããŸã
äŸ:
// id='js' ã®æ¬ãåé€ããŸã
books.delete('js');
äŸ¡æ Œ ãããã¯å¥ã®ãªããžã§ã¯ããã£ãŒã«ããå
ã«æ¬ãåé€ãããå Žåã¯ãæåã« index ã§ããŒãèŠã€ãããã®åŸã« delete ãåŒã³åºããŸãã:
// price = 5 ã®ããŒãèŠã€ãã
let request = priceIndex.getKey(5);
request.onsuccess = function() {
let id = request.result;
let deleteRequest = books.delete(id);
};
ãã¹ãŠã®åé€ããã«ã¯:
books.clear(); // ã¹ãã¬ãŒãžãã¯ãªã¢ããŸã
ã«ãŒãœã«ïŒCursorsïŒ
getAll/getAllKeys ã®ãããªã¡ãœãã㯠ããŒ/å€ ã®é
åãè¿ããŸãã
ã§ããããªããžã§ã¯ãã¹ãã¬ãŒãžã¯å·šå€§ã«ãªããå©çšå¯èœãªã¡ã¢ãªããã倧ãããªãå¯èœæ§ããããŸããgetAll ã¯ãã¹ãŠã®ã¬ã³ãŒããé
åãšããŠååŸããããšã¯ã§ããªãã§ãããã
äœããããããã§ãããïŒ
ã«ãŒãœã«ã¯ãããåé¿ããææ®µãæäŸããŸãã
ã«ãŒãœã« ã¯äžããããã¯ãšãªã§ãªããžã§ã¯ãã¹ãã¬ãŒãžã暪æããç¹å¥ãªãªããžã§ã¯ãã§ãäžåºŠã«1ã€ã®ããŒ/å€ãè¿ããããã¡ã¢ãªãç¯çŽããŸãã
ãªããžã§ã¯ãã¹ãã¢ã¯å éšçã«ã¯ããŒã§ãœãŒããããŠããã®ã§ãã«ãŒãœã«ã¯ããŒé ïŒããã©ã«ãã§ã¯æé ïŒã§ã¹ãã¢ãç§»åããŸãã
æ§æ:
// getAll ãšäŒŒãŠããŸãã ã«ãŒãœã«ã«å¯ŸããŠã§ã:
let request = store.openCursor(query, [direction]);
// å€ã§ã¯ãªãããŒãåŸãã«ã¯ïŒgetAllKeysã®ãããªïŒ: store.openKeyCursor
queryã¯ããŒãŸãã¯ããŒç¯å²ã§ãgetAllãšåãã§ããdirectionã¯ãªãã·ã§ã³ã®åŒæ°ã§ã䜿çšããé åºã§ã:"next"â ããã©ã«ãã§, ã«ãŒãœã«ã¯æãå°ããããŒã®ã¬ã³ãŒãããäžã«ç§»åããŸãã"prev"â éé ã§ã: æã倧ããªããŒãæã€ã¬ã³ãŒãããäžã«ç§»åããŸãã"nextunique","prevunique"â äžãšåãã§ãããåãããŒãæã€ã¬ã³ãŒããã¹ãããããŸãïŒindex äžã®ã«ãŒãœã«ã®ã¿ãäŸ: price=5 ã®è€æ°ã®æ¬ã®å Žåãæåã®1åã ããè¿åŽãããŸãïŒã
ã«ãŒãœã«ã®äž»ãªéã㯠request.onsuccess ãè€æ°åããªã¬ãŒãããããšã§ã: åçµæã«å¯Ÿã1床ããªã¬ãŒãããŸãã
ããã¯ãã«ãŒãœã«ã®äœ¿çšäŸã§ã:
let transaction = db.transaction("books");
let books = transaction.objectStore("books");
let request = books.openCursor();
// ã«ãŒãœã«ã§èŠã€ãã£ã忬ã«å¯ŸããŠåŒã³åºãããŸã
request.onsuccess = function() {
let cursor = request.result;
if (cursor) {
let key = cursor.key; // book key (id ãã£ãŒã«ã)
let value = cursor.value; // book ãªããžã§ã¯ã
console.log(key, value);
cursor.continue();
} else {
console.log("No more books");
}
};
äž»ãªã«ãŒãœã«ã¡ãœããã¯ä»¥äžã§ã:
advance(count)â ã«ãŒãœã«ãcountæ°é²ããå€ãã¹ãããããŸããcontinue([key])â ãããããç¯å²ã®æ¬¡ã®å€ã«ã«ãŒãœã«ãé²ããŸãïŒãããã¯æå®ãããå Žåã¯ããã®keyã®çŽåŸïŒ
ã«ãŒãœã«ã«äžèŽããå€ããã£ãšãããåŠãã¯ãonsuccess ãåŒã³åºããåŸ result ãèŠãããšã§ã次ã®ã¬ã³ãŒããæãã«ãŒãœã«ããã㯠undefined ãååŸã§ããŸãã
äžèšã®äŸã§ã¯ããªããžã§ã¯ãã¹ãã¢çšã®ã«ãŒãœã«ãäœæãããŸããã
ããããindex äžã«ã«ãŒãœã«ãäœæããããšãã§ããŸãã埡åç¥ã®éããindex ãå©çšããããšã§ãªããžã§ã¯ããã£ãŒã«ãã§æ€çŽ¢ããããšãã§ããŸããindex äžã®ã«ãŒãœã«ã¯ãªããžã§ã¯ãã¹ãã¢äžã®ã«ãŒãœã«ãšãŸã£ããåãããã«æ©èœããŸããã€ãŸããäžåºŠã«ïŒã€ã®å€ãè¿ãããšã§ã¡ã¢ãªãç¯çŽããŸãã
index äžã®ã«ãŒãœã«ã®å Žåãcursor.key 㯠index ããŒïŒäŸ, price ïŒã§ããããªããžã§ã¯ãããŒã«å¯ŸããŠã¯ cursor.primaryKey ããããã£ã䜿çšããå¿
èŠããããŸã:
let request = priceIdx.openCursor(IDBKeyRange.upperBound(5));
// called for each record
request.onsuccess = function() {
let cursor = request.result;
if (cursor) {
let primaryKey = cursor.primaryKey; // 次ã®ãªããžã§ã¯ãã¹ãã¢ããŒ(id ãã£ãŒã«ã)
let value = cursor.value; // 次ã®ãªããžã§ã¯ãã¹ãã¢ãªããžã§ã¯ã (book ãªããžã§ã¯ã)
let key = cursor.key; // 次㮠index ã㌠(price)
console.log(key, value);
cursor.continue();
} else {
console.log("No more books");
}
};
Promise ã©ãããŒ
ãã¹ãŠã®ãªã¯ãšã¹ãã« onsuccess/onerror ã远å ããã®ã¯ãšãŠãé¢åãªäœæ¥ã§ããã€ãã³ãå§è²ã䜿çšããããšã§ã楜ã«ã§ããå ŽåãããããšããããŸããäŸãã°ããã©ã³ã¶ã¯ã·ã§ã³å
šäœã«ãã³ãã©ãèšå®ããŸãããasync/await ã¯ã¯ããã«äŸ¿å©ã§ãã
ãã®ãã£ãã¿ãŒã§ã¯ãèãPromise ã©ãã㌠https://github.com/jakearchibald/idb ã䜿ã£ãŠã¿ãŸãããããã㯠promise å ããã IndexedDB ã¡ãœãããæã€ãã°ããŒãã«ãª idb ãªããžã§ã¯ããçæããŸãã
ãããšãonsuccess/onerror ã®ä»£ããã«ã次ã®ããã«èšè¿°ããããšãã§ããŸã:
let db = await idb.openDB('store', 1, db => {
if (db.oldVersion == 0) {
// åæåã®å®è¡
db.createObjectStore('books', {keyPath: 'id'});
}
});
let transaction = db.transaction('books', 'readwrite');
let books = transaction.objectStore('books');
try {
await books.add(...);
await books.add(...);
await transaction.complete;
console.log('jsbook saved');
} catch(err) {
console.log('error', err.message);
}
âéåžžã® async ã³ãŒãâ ãš âtryâŠcatchâ ã ãã«ãªããŸãã
ãšã©ãŒãã³ããªã³ã°
ãšã©ãŒããã£ããããªãå Žåãæãè¿ãå€åŽã® try...catch ãŸã§ãšã©ãŒãããŸãã
ãã£ãããããªãã£ããšã©ãŒã¯ window ãªããžã§ã¯ãã®"æªåŠçã® prmise æåŠ" ã€ãã³ãã«ãªããŸãã
次ã®ããã«ããŠããã®ãããªãšã©ãŒãåŠçããããšãã§ããŸã:
window.addEventListener('unhandledrejection', event => {
let request = event.target; // IndexedDB ãã€ãã£ãã®ãªã¯ãšã¹ããªããžã§ã¯ã
let error = event.reason; // æªåŠçã®ãšã©ãŒãªããžã§ã¯ããrequest.error ãšåã
...report about the error...
});
âéã¢ã¯ãã£ããªãã©ã³ã¶ã¯ã·ã§ã³â ã®èœãšã穎
ãã§ã«ãåç¥ã®ããã«ããã©ãŠã¶ãçŸåšã®ã³ãŒããš microtask ãå®è¡ãããšããã«ãã©ã³ã¶ã¯ã·ã§ã³ã¯èªåã³ããããããŸãããã®ããããã©ã³ã¶ã¯ã·ã§ã³äžã« fetch ã®ãã㪠macrotask ã眮ããå Žåããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã®çµäºãåŸ
ããèªåã³ãããããŸãããããã£ãŠã次ã®ãªã¯ãšã¹ãã¯å€±æããã§ãããã
promise ã©ãããŒã async/await ã®å Žåãåãã§ãã
ããã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®éäžã« fetch ãããäŸã§ã:
let transaction = db.transaction("inventory", "readwrite");
let inventory = transaction.objectStore("inventory");
await inventory.add({ id: 'js', price: 10, created: new Date() });
await fetch(...); // (*)
await inventory.add({ id: 'js', price: 10, created: new Date() }); // Error
fetch (*) ã®åŸã«ããæ¬¡ã® inventory.add 㯠âéã¢ã¯ãã£ããªãã©ã³ã¶ã¯ã·ã§ã³â ãšã©ãŒã§å€±æããŸãããã®æç¹ã§ãã©ã³ã¶ã¯ã·ã§ã³ã¯æ¢ã«ã³ãããããã¯ããŒãºãããŠããããã§ãã
åé¿çã¯ãã€ãã€ãã®IndexedDB ã䜿çšããå Žåãšåãã§ããæ°ããªãã©ã³ã¶ã¯ã·ã§ã³ãäœãããåã«ç©äºãåå²ããããã§ãã
- ããŒã¿ãæºåããæåã«å¿ èŠãªãã®ããã¹ãŠååŸããŸãã
- 次ã«ãããŒã¿ããŒã¹ã«ä¿åããŸãã
ãã€ãã£ããªããžã§ã¯ããååŸãã
å
éšçã«ã¯ãã©ãããŒã¯ onerror/onsuccess ã远å ããããã€ãã€ãã® IndexedDB ãªã¯ãšã¹ããå®è¡ãããã®çµæã reject/resolve ãã promise ãè¿ããŸãã
ã»ãšãã©ã®å Žåãããã§åé¡ãªãåäœããŸããäŸã¯ã©ã€ãã©ãªã®ããŒãž https://github.com/jakearchibald/idb ã«ãããŸãã
ã¬ã¢ã±ãŒã¹ã§ããããªãªãžãã«ã® request ãªããžã§ã¯ããå¿
èŠãªãšãã¯ãpromise ã® promise.request ããããã£ã§ã¢ã¯ã»ã¹ããããšãã§ããŸã:
let promise = books.add(book); // promise ãååŸããŸã (await ã¯äžèŠ)
let request = promise.request; // ãã€ãã£ãã®ãªã¯ãšã¹ããªããžã§ã¯ã
let transaction = request.transaction; // ãã€ãã£ãã®ãã©ã³ã¶ã¯ã·ã§ã³ãªããžã§ã¯ã
// ...do some native IndexedDB voodoo...
let result = await promise; // å¿
èŠã§ããã°
ãµããª
IndexedDB ã¯ã·ã³ãã«ãª key-value ããŒã¿ããŒã¹ã§ããããªãã©ã€ã³ã¢ããªã±ãŒã·ã§ã³ã«ã¯åå匷åãªãã®ã§ããã€ã€ã䜿ãããããã®ã§ãã
æè¯ã®ããã¥ã¢ã«ã¯ä»æ§ã§ããçŸåšã®ï¿œï¿œã® 㯠2.0 ã§ããã3.0 ã®ããã€ãã®ã¡ãœããïŒå€§ããªéãã¯ãããŸããïŒã¯éšåçã«ãµããŒããããŠããŸãã
åºæ¬çãªäœ¿ç𿹿³ã¯æ¬¡ã®ãã§ãŒãºã§èª¬æã§ããŸã:
- idb ã®ãã㪠promise ã©ãããŒãååŸããŸãã
- ããŒã¿ããŒã¹ããªãŒãã³ããŸã
idb.openDb(name, version, onupgradeneeded) - ãªã¯ãšã¹ãã®å Žå:
- ãã©ã³ã¶ã¯ã·ã§ã³ãäœæããŸã
db.transaction('books')(å¿ èŠã«å¿ããŠèªã¿æžã)ã - ãªããžã§ã¯ãã¹ãã¢ãååŸããŸã
transaction.objectStore('books')ã
- ãã©ã³ã¶ã¯ã·ã§ã³ãäœæããŸã
- 次ã«ãããŒã§æ€çŽ¢ããããã«ãªããžã§ã¯ãã¹ãã¢ã®ã¡ãœãããçŽæ¥åŒã³åºããŸãã
- ãªããžã§ã¯ããã£ãŒã«ãã§æ€çŽ¢ããå Žåã«ã¯ index ãäœæããŸãã
- ããŒã¿ãã¡ã¢ãªã«åãŸããªãå Žåã«ã¯ãã«ãŒãœã«ã䜿çšããŸãã
ããã¯å°ããªãã¢ã¢ããªã§ã:
<!doctype html>
<script src="https://cdn.jsdelivr.net/npm/idb@3.0.2/build/idb.min.js"></script>
<button onclick="addBook()">Add a book</button>
<button onclick="clearBooks()">Clear books</button>
<p>Books list:</p>
<ul id="listElem"></ul>
<script>
let db;
init();
async function init() {
db = await idb.openDb('booksDb', 1, db => {
db.createObjectStore('books', {keyPath: 'name'});
});
list();
}
async function list() {
let tx = db.transaction('books');
let bookStore = tx.objectStore('books');
let books = await bookStore.getAll();
if (books.length) {
listElem.innerHTML = books.map(book => `<li>
name: ${book.name}, price: ${book.price}
</li>`).join('');
} else {
listElem.innerHTML = '<li>No books yet. Please add books.</li>'
}
}
async function clearBooks() {
let tx = db.transaction('books', 'readwrite');
await tx.objectStore('books').clear();
await list();
}
async function addBook() {
let name = prompt("Book name?");
let price = +prompt("Book price?");
let tx = db.transaction('books', 'readwrite');
try {
await tx.objectStore('books').add({name, price});
await list();
} catch(err) {
if (err.name == 'ConstraintError') {
alert("Such book exists already");
await addBook();
} else {
throw err;
}
}
}
window.addEventListener('unhandledrejection', event => {
alert("Error: " + event.reason.message);
});
</script>
ã³ã¡ã³ã
<code>ã¿ã°ã䜿ã£ãŠãã ãããè€æ°è¡ã®å Žåã¯<pre>ãã10è¡ãè¶ ããå Žåã«ã¯ãµã³ãããã¯ã¹ã䜿ã£ãŠãã ãã(plnkr, JSBin, codepenâŠ)ã