这次先不封装增删改查了,而是先看看执行顺序到底是什么样子的。
我们给 help 里面加上一些标记:
import { isRef, isReactive, toRaw } from 'vue'
export default class IndexedDBHelp {
constructor (info) {
this.myIndexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB
// 记录连接数据库的对象
this._db = null
// 打开数据库
this.dbRequest = this.myIndexedDB.open(info.dbName, info.ver)
console.log('【0】开启数据库 ')
// 打开成功,记录连接对象
this.dbRequest.onsuccess = (event) => {
this._db = event.target.result // dbRequest.result
console.log('【1】成功打开数据库 onsuccess --- ', this._db)
}
// 根据配置信息建立表
this.dbRequest.onupgradeneeded = (event) => {
const db = event.target.result
console.log('【2】升级数据库 onupgradeneeded --- ', db)
// 建表
const object = {
objectStoreName: 'aa'
}
// 验证有没有,没有的话建立一个对象表
if (!db.objectStoreNames.contains(object.objectStoreName)) {
const objectStore = db.createObjectStore(object.objectStoreName, { autoIncrement: true })
}
}
}
// 读写的事务
beginWrite (storeName) {
return new Promise((resolve, reject) => {
const _tran = () => {
const tranRequest = this._db.transaction(storeName, 'readwrite')
tranRequest.onerror = (event) => {
console.log('读写事务出错:', event.target.error)
reject('读写事务出错:' + event.target.error)
}
resolve(tranRequest)
}
if (this._db) {
console.log('【11】内部开启事务,获得对象 ')
_tran() // 执行事务
} else {
console.log('【10】内部没有获得对象,使用计时器 ')
let i = 0
const val = setInterval(() => {
console.log(`【11】 内部计时器: ${i++} --- `, this.dbRequest.readyState)
// 检查 _db 和状态
if (this._db && this.dbRequest.readyState === 'done') {
console.log(`【12】 取消计时器: ${i++} --- `, this._db)
console.log(`【13】 取消计时器: ${i} --- `, this.dbRequest.readyState)
clearInterval(val) // 取消
_tran() // 执行事务
}
}, 2)
}
})
}
使用代码
const info = {
dbName: 'test',
ver: 1
}
const help = new IndexedDB(info)
console.log('help', help)
console.log('【3】外部 读取 开启状态 readyState', help.dbRequest.readyState)
const model = {
id: new Date().valueOf(),
name: 'jyk666',
age: 19
}
help.beginWrite(['aa']).then((tran) => {
addModel(help, 'aa', model, tran)
})
然后看看执行情况。
没有建立数据库的情况
第一次执行,肯定没有数据库,这时候会触发 onupgradeneeded ,那么问题来了,它和 onsuccess 谁先回调?还有这期间 dbRequest.readyState 都是啥状态?
我们来运行看看:
没有数据库的情况过程:想要打开数据库 =》 触发建表(onupgradeneeded)=》成功打开数据库(onsuccess)
同时:计时器等待中。。。
最后:执行添加操作。
执行结果事实证明,dbRequest.readyState 并不靠谱,onupgradeneeded 之后就变成了 none了,但是此时还在建表中,并没有执行 onsuccess 。所以还是需要判断 _db。
有数据库的情况
有了数据库 , onupgradeneeded 就不会被执行(ver不变的情况下),那么来看看执行情况:
已经有数据库这次就简单多了,计时器等待一轮,就拿到了连接对象。
升级数据库的情况
如果版本号升级,又会如何?还是来看看执行情况:
升级数据库版本号升级,又触发了 onupgradeneeded ,流程和没有数据的差不多。
修改版本号,然后保存文件,这时 vite 会自动更新,但是会触发计时器的死循环。这时需要刷新一下页面。具体原因不详。
网友评论