打开数据库
语法:
indexedDB.open(name, version)
复制代码
例子:
var req = indexedDB.open('store', 1)
复制代码
注意:
参数 version
必须是大于 0 的自然数,否则报错。
使用 0
:
indexedDB.open('store', 0)
// Uncaught TypeError: Failed to execute 'open' on 'IDBFactory': The version provided must not be 0.
复制代码
使用负值:
indexedDB.open('store', -1)
// Uncaught TypeError: Failed to execute 'open' on 'IDBFactory': Value is outside the 'unsigned long long' value range.
复制代码
req
是打开数据库后,返回的请求实例。如果成功打开数据库,通过 req.result
可获得数据库连接实例。
// 监听 `req` 的 success 事件
req.onsuccess = function() {
// 成功打开数据库,就可获得数据库连接实例
var db = storeReq.result
console.log('success: continue to work with database using `db` object')
}
复制代码
除了 success
,还有 upgradeneeded
、error
事件:
req.onupgradeneeded = function() {
var db = storeReq.result
console.log(`upgradeneeded: client had version ${db.version}`)
}
req.onerror = function() {
console.log('error:', storeReq.error)
}
复制代码
indexedDB.open
有以下几种情况:
一、打开之前不存在的数据库
upgradeneeded: client had version 1
success: continue to work with database using `db` object
复制代码
二、升级数据库版本(如:indexedDB.open('store', 2)
,之前存储的版本号为 1
)
upgradeneeded: client had version 2
success: continue to work with database using `db` object
复制代码
三、打开数据库使用的版本比现有的低
比如:之前使用 indexedDB.open('store', 2)
打开过,现在使用 indexedDB.open('store', 1)
打开。
error: DOMException: The requested version (1) is less than the existing version (2).
复制代码
四、打开已有数据库
success: continue to work with database using `db` object
复制代码
删除数据库
语法:
indexedDB.deleteDatabase(name)
复制代码
直接指定数据库名即可,无需带上版本号。 例子:
var delReq = indexedDB.deleteDatabase('store')
delReq.onerror = function(event) {
console.log('Error deleting database.')
}
delReq.onblocked = function(event) {
console.log('Blocked deleting database.')
}
delReq.onsuccess = function(event) {
console.log('Database deleted successfully')
console.log(event.result) // should be undefined
}
复制代码
这里需要注意的问题是:如果删除的数据库(如这里的 “store
”)已被打开,那么执行 indexedDB.deleteDatabase('store')
后,会触发 delReq
的 blocked
事件,而非是 success
事件。
// 打开数据库 store
var req = indexedDB.open('store', 1)
// ...
// 删除数据库
var delReq = indexedDB.deleteDatabase('store')
delReq.onblocked = function(event) {
console.log('Blocked deleting database.')
}
// 输出:
// Blocked deleting database.
复制代码
删除数据库遭到阻塞,是因为数据库连接实例 db
没有关闭。我们给 db
添加 onversionchange
事件,就能看出来:
// 打开数据库 store
var req = indexedDB.open('store', 1)
// 监听 `req` 的 success 事件
req.onsuccess = function() {
// 成功打开数据库,就可获得数据库连接实例
var db = storeReq.result
db.onversionchange = function() {
console.log('Database is outdated, please reload the page.')
}
console.log('success: continue to work with database using `db` object')
}
// 删除数据库
var delReq = indexedDB.deleteDatabase('store')
delReq.onblocked = function(event) {
console.log('Blocked deleting database.')
}
// 输出:
// Database is outdated, please reload the page.
// Blocked deleting database.
复制代码
再看输出,发现 db.onversionchange
触发在前,delReq.onblocked
触发在后。原因就在于:删除数据库,没有把已有的数据库连接关闭。我们在 db.onversionchange
中,使用 db.close()
关闭连接。再来看看结果:
// 打开数据库 store
var req = indexedDB.open('store', 1)
// 监听 `req` 的 success 事件
req.onsuccess = function() {
// 成功打开数据库,就可获得数据库连接实例
var db = storeReq.result
db.onversionchange = function() {
+ db.close()
console.log('Database is outdated, please reload the page.')
}
console.log('success: continue to work with database using `db` object')
}
// 删除数据库
var delReq = indexedDB.deleteDatabase('store')
delReq.onblocked = function(event) {
console.log('Blocked deleting database.')
}
+ delReq.onsuccess = function(event) {
+ console.log('Database deleted successfully')
+ }
// 输出:
// Database is outdated, please reload the page.
- // Blocked deleting database.
+ // Database deleted successfully
复制代码
数据库成功删除了。
注意:
即使前面删除时没有关闭数据库链接,导致触发 delReq
的 blocked
事件,但实际上数据库 store
也是被成功删除了的(刷新页面就能看到数据库已被删除)。
升级数据库
升级数据库版本的时候,也要注意已经打开的数据库连接。如果现有的数据库连接没有关闭,调用 var newReq = indexedDB.open('store', 2)
就会触发 newReq
的 blocked
事件。
let req = indexedDB.open('store', 1)
req.onupgradeneeded = function() {
var db = req.result
console.log(`[req] upgradeneeded: client had version ${db.version}`)
}
req.onsuccess = function() {
var db = req.result
db.onversionchange = function() {
console.log('[req] Database is outdated, please reload the page.')
}
console.log('[req] success: continue to work with database using `db` object')
}
// 3 秒后,使用新版本号打开数据库
setTimeout(() => {
var newReq = indexedDB.open('store', 2)
newReq.onblocked = function() {
console.log('[newReq] onblocked:')
console.log(newReq.error)
}
newReq.onsuccess = function() {
console.log(
'[newReq] success: continue to work with database using `db` object'
)
}
}, 3000)
// 输出:
// [req] upgradeneeded: client had version 1
// [req] success: continue to work with database using `db` object
// [req] Database is outdated, please reload the page.
// [newReq] onblocked:
// Uncaught DOMException: Failed to read the 'error' property from 'IDBRequest': The request has not finished.
复制代码
在现有的数据库连接没有关闭的情况下,使用新版本号打开数据库同样会触发已有数据库连接实例的 versionchange
事件,如果不在此事件中关闭连接,则打开数据库失败。
我们将关闭连接的逻辑加上试试:
let req = indexedDB.open('store', 1)
req.onupgradeneeded = function() {
var db = req.result
console.log(`[req] upgradeneeded: client had version ${db.version}`)
}
req.onsuccess = function() {
var db = req.result
db.onversionchange = function() {
+ db.close()
console.log('[req] Database is outdated, please reload the page.')
}
console.log('[req] success: continue to work with database using `db` object')
}
// 3 秒后,使用新版本号打开数据库
setTimeout(() => {
var newReq = indexedDB.open('store', 2)
newReq.onblocked = function() {
console.log('[newReq] onblocked:')
console.log(newReq.error)
}
newReq.onsuccess = function() {
console.log(
'[newReq] success: continue to work with database using `db` object'
)
}
}, 3000)
// 输出:
// [req] upgradeneeded: client had version 1
// [req] success: continue to work with database using `db` object
// [req] Database is outdated, please reload the page.
- // [newReq] onblocked:
- // Uncaught DOMException: Failed to read the 'error' property from 'IDBRequest': The request has not finished.
+ [newReq] success: continue to work with database using `db` object
复制代码
打开新版数据库实例成功~
(正文完)
广告时间(长期有效)
我有一位好朋友开了一间猫舍,在此帮她宣传一下。现在猫舍里养的都是布偶猫。如果你也是个爱猫人士并且有需要的话,不妨扫一扫她的【闲鱼】二维码。不买也不要紧,看看也行。
(完)