Last active
June 16, 2018 20:43
-
-
Save NevenLeung/df798eb846a4d75cae7a12aec432a0ff to your computer and use it in GitHub Desktop.
some indexedDB operation wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const indexedDBModule = function(dbName, version, objectStorage) { | |
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; | |
const dbOpenRequest = window.indexedDB.open(dbName, version); | |
// 模块中的局部变量,用于存储连接成功的数据库连接 | |
let db; | |
dbOpenRequest.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
reject(event.target); | |
}; | |
dbOpenRequest.onupgradeneeded = function () { | |
const db = dbOpenRequest.result; | |
// 创建存储空间,使用自增的主值 | |
const store = db.createObjectStore(objectStorage, { | |
keyPath: '_id', | |
autoIncrement: true | |
}); | |
}; | |
dbOpenRequest.onsuccess = function () { | |
db = dbOpenRequest.result; | |
} | |
function useIndexedDB(action, dataParam) { | |
return new Promise(function(resolve, reject) { | |
// 创建事务 | |
const transaction = db.transaction(objectStorage, 'readwrite'); | |
// 在事务上得到相应的存储空间,用于数据的读取与修改 | |
const objectStore = transaction.objectStore(objectStorage); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
let txOperationRequest; | |
switch (action) { | |
case 'getAll': | |
txOperationRequest = objectStore.getAll(); | |
break; | |
case 'get': | |
txOperationRequest = objectStore.get(dataParam); | |
break; | |
case 'post': | |
txOperationRequest = objectStore.add(dataParam); | |
break; | |
case 'put': | |
txOperationRequest = objectStore.put(dataParam); | |
break; | |
case 'delete': | |
txOperationRequest = objectStore.delete(dataParam); | |
break; | |
case 'removeAll': | |
txOperationRequest = objectStore.clear(); | |
} | |
txOperationRequest.onerror = function (event) { | |
console.log(event.target); | |
reject(event.target); | |
}; | |
txOperationRequest.onsuccess = function (event) { | |
switch (action) { | |
case 'getAll': | |
resolve(txOperationRequest.result); | |
break; | |
case 'get': | |
resolve(txOperationRequest.result); | |
break; | |
case 'post': | |
console.log(`Item with _id ${txOperationRequest.result} has been added.`); | |
resolve({ _id: txOperationRequest.result}); | |
break; | |
case 'put': | |
console.log(`Item with _id ${txOperationRequest.result} has been updated.`); | |
resolve({ _id: txOperationRequest.result }); | |
break; | |
case 'delete': | |
console.log('Item has been removed.'); | |
resolve('Item has been removed.'); | |
break; | |
case 'removeAll': | |
console.log('All items have been removed.'); | |
resolve('All items have been removed.'); | |
} | |
}; | |
}); | |
}; | |
return { | |
getAll: function () { | |
return useIndexedDB('getAll', ''); | |
}, | |
get: function (query) { | |
return useIndexedDB('get', query); | |
}, | |
create: function (data) { | |
return useIndexedDB('post', data); | |
}, | |
// update: function(query, data) { | |
// return useIndexedDB('get', query) | |
// .then(function(result) { | |
// if (typeof result !== 'undefined') { | |
// const newData = Object.assign(result, data); | |
// return useIndexedDB('put', newData); | |
// } else { | |
// console.log('Can not find the data according to the query'); | |
// } | |
// }).catch(function(err) { | |
// console.error(err); | |
// }) | |
// }, | |
update: async function (query, data){ | |
try { | |
const queryResult = await useIndexedDB('get', query); | |
if (typeof queryResult !== 'undefined') { | |
const newData = Object.assign(queryResult, data); | |
return useIndexedDB('put', newData); | |
} else { | |
console.log('Can not find the data according to the query'); | |
} | |
} | |
catch (err) { | |
console.error(err); | |
} | |
}, | |
// put: function (data) { | |
// return useIndexedDB('put', data); | |
// }, | |
delete: function (query) { | |
return useIndexedDB('delete', query); | |
}, | |
removeAll: function () { | |
return useIndexedDB('removeAll', ''); | |
}, | |
} | |
}; | |
const todoStore = indexedDBModule('TodoApp', 1, 'todo'); | |
// usage | |
// // getAll | |
// todoStore.getAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // get | |
// todoStore.get(query) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // create | |
// todoStore.create(data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // update | |
// todoStore.update(query, data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // delete | |
// todoStore.delete(query) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // removeAll | |
// todoStore.removeAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const indexedDBModule = function(dbName, version, objectStorage) { | |
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; | |
const dbOpenRequest = window.indexedDB.open(dbName, version); | |
// 模块中的局部变量,用于存储连接成功的数据库连接 | |
let db; | |
dbOpenRequest.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
reject(event.target); | |
}; | |
dbOpenRequest.onupgradeneeded = function () { | |
const db = dbOpenRequest.result; | |
// 创建存储空间,使用自增的主值 | |
const store = db.createObjectStore(objectStorage, { | |
keyPath: '_id', | |
autoIncrement: true | |
}); | |
}; | |
dbOpenRequest.onsuccess = function () { | |
db = dbOpenRequest.result; | |
} | |
function useIndexedDB(action, dataParam) { | |
return new Promise(function(resolve, reject) { | |
// 创建事务 | |
const transaction = db.transaction(objectStorage, 'readwrite'); | |
// 在事务上得到相应的存储空间,用于数据的读取与修改 | |
const objectStore = transaction.objectStore(objectStorage); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
let txOperationRequest; | |
switch (action) { | |
case 'getAll': | |
txOperationRequest = objectStore.getAll(); | |
break; | |
case 'get': | |
txOperationRequest = objectStore.get(dataParam); | |
break; | |
case 'post': | |
txOperationRequest = objectStore.add(dataParam); | |
break; | |
case 'put': | |
txOperationRequest = objectStore.put(dataParam); | |
break; | |
case 'delete': | |
txOperationRequest = objectStore.delete(dataParam); | |
break; | |
case 'removeAll': | |
txOperationRequest = objectStore.clear(); | |
} | |
txOperationRequest.onerror = function (event) { | |
console.log(event.target); | |
reject(event.target); | |
}; | |
txOperationRequest.onsuccess = function (event) { | |
switch (action) { | |
case 'getAll': | |
resolve(txOperationRequest.result); | |
break; | |
case 'get': | |
resolve(txOperationRequest.result); | |
break; | |
case 'post': | |
console.log(`Item with _id ${txOperationRequest.result} has been added.`); | |
resolve({ _id: txOperationRequest.result}); | |
break; | |
case 'put': | |
console.log(`Item with _id ${txOperationRequest.result} has been updated.`); | |
resolve({ _id: txOperationRequest.result }); | |
break; | |
case 'delete': | |
console.log('Item has been removed.'); | |
resolve('Item has been removed.'); | |
break; | |
case 'removeAll': | |
console.log('All items have been removed.'); | |
resolve('All items have been removed.'); | |
} | |
}; | |
}); | |
}; | |
return { | |
getAll: function () { | |
return useIndexedDB('getAll', ''); | |
}, | |
get: function (query) { | |
return useIndexedDB('get', query); | |
}, | |
create: function (data) { | |
return useIndexedDB('post', data); | |
}, | |
update: function(query, data) { | |
return useIndexedDB('get', query) | |
.then(function(result) { | |
if (typeof result !== 'undefined') { | |
const newData = Object.assign(result, data); | |
return useIndexedDB('put', newData); | |
} else { | |
console.log('Can not find the data according to the queryString'); | |
} | |
}).catch(function(err) { | |
console.error(err); | |
}) | |
}, | |
// put: function (data) { | |
// return useIndexedDB('put', data); | |
// }, | |
delete: function (query) { | |
return useIndexedDB('delete', query); | |
}, | |
removeAll: function () { | |
return useIndexedDB('removeAll', ''); | |
}, | |
} | |
}; | |
const todoStore = indexedDBModule('TodoApp', 1, 'todo'); | |
// usage | |
// // getAll | |
// todoStore.getAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // get | |
// todoStore.get(query) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // add | |
// todoStore.add(data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // update | |
// todoStore.update(query, data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // delete | |
// todoStore.delete(query) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // removeAll | |
// todoStore.removeAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const todoStore = (function(dbName='TodoApp', version=1, objectStorage='todo') { | |
function useIndexedDB(action, dataParam) { | |
return new Promise(function(resolve, reject) { | |
const dbOpenRequest = window.indexedDB.open(dbName, version); | |
dbOpenRequest.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
reject(event.target); | |
}; | |
dbOpenRequest.onupgradeneeded = function () { | |
const db = dbOpenRequest.result; | |
// 创建存储空间,使用自增的主值 | |
const store = db.createObjectStore(objectStorage, { | |
keyPath: '_id', | |
autoIncrement: true | |
}); | |
}; | |
dbOpenRequest.onsuccess = function () { | |
const db = dbOpenRequest.result; | |
// 创建事务 | |
const transaction = db.transaction(objectStorage, 'readwrite'); | |
// 在事务上得到相应的存储空间,用于数据的读取与修改 | |
const objectStore = transaction.objectStore(objectStorage); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
let txOperationRequest; | |
switch (action) { | |
case 'getAll': | |
txOperationRequest = objectStore.getAll(); | |
break; | |
case 'get': | |
txOperationRequest = objectStore.get(dataParam); | |
break; | |
case 'post': | |
txOperationRequest = objectStore.add(dataParam); | |
break; | |
case 'put': | |
txOperationRequest = objectStore.put(dataParam); | |
break; | |
case 'delete': | |
txOperationRequest = objectStore.delete(dataParam); | |
break; | |
case 'removeAll': | |
txOperationRequest = objectStore.clear(); | |
} | |
txOperationRequest.onerror = function (event) { | |
console.log(event.target); | |
reject(event.target); | |
}; | |
txOperationRequest.onsuccess = function (event) { | |
switch (action) { | |
case 'getAll': | |
resolve(txOperationRequest.result); | |
break; | |
case 'get': | |
resolve(txOperationRequest.result); | |
break; | |
case 'post': | |
console.log(`Item with _id ${txOperationRequest.result} has been added.`); | |
resolve({ _id: txOperationRequest.result}); | |
break; | |
case 'put': | |
console.log(`Item with _id ${txOperationRequest.result} has been updated.`); | |
resolve({ _id: txOperationRequest.result }); | |
break; | |
case 'delete': | |
console.log('Item has been removed.'); | |
resolve('Item has been removed.'); | |
break; | |
case 'removeAll': | |
console.log('All items have been removed.'); | |
resolve('All items have been removed.'); | |
} | |
}; | |
transaction.oncomplete = function () { | |
db.close(); | |
}; | |
}; | |
}); | |
} | |
return { | |
getAll: function () { | |
return useIndexedDB('getAll', ''); | |
}, | |
get: function (queryString) { | |
return useIndexedDB('get', queryString); | |
}, | |
add: function (data) { | |
return useIndexedDB('post', data); | |
}, | |
update: function(queryString, data) { | |
return useIndexedDB('get', queryString) | |
.then(function(result) { | |
if (typeof result !== 'undefined') { | |
const newData = Object.assign(result, data); | |
return useIndexedDB('put', newData); | |
} else { | |
console.log('Can not find the data according to the queryString'); | |
} | |
}).catch(function(err) { | |
console.error(err); | |
}) | |
}, | |
// put: function (data) { | |
// return useIndexedDB('put', data); | |
// }, | |
delete: function (queryString) { | |
return useIndexedDB('delete', queryString); | |
}, | |
removeAll: function () { | |
return useIndexedDB('removeAll', ''); | |
}, | |
} | |
}()); | |
// usage | |
// // getAll | |
// todoStore.getAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // get | |
// todoStore.get(queryString) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // add | |
// todoStore.add(data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // update | |
// todoStore.update(queryString, data) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // delete | |
// todoStore.delete(queryString) | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) | |
// // removeAll | |
// todoStore.removeAll() | |
// .then((result) => { | |
// if (result) { | |
// // your code | |
// } | |
// }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 待写入数据 | |
const users = [ | |
{ | |
userID: '001', | |
username: 'Cherry' | |
}, | |
{ | |
userID: '002', | |
username: 'Rachel' | |
}, | |
{ | |
userID: '003', | |
username: 'Amy' | |
}, | |
{ | |
userID: '004', | |
username: 'david' | |
}, | |
{ | |
userID: '005', | |
username: 'Mia' | |
} | |
]; | |
/** | |
* useIndexedDB() useIndexedDB() 利用indexedDB进行单条数据的增删改查,还支持获取或删除数据库的所有数据 | |
* | |
* @param {String} action 数据库操作行为,getAll|get|add|update|remove|removeAll | |
* @param {String|Object} dataParam 与行为对应的数据参数 | |
* getAll|removeAll 不需要参数, | |
* add|update 需要一个想要新增或更新的数据object, | |
* get|remove 需要一个数据库主值的value | |
* @param {String} dbName 数据库名称,默认为testing | |
* @param {Number} version 数据库版本号,为正整数,默认为1 | |
* @param {String} objectStorageName 对象存储空间名称,相对于SQL的table name,默认为users | |
* @param {String} keyPath 对象存储空间的主值(对象中的属性名称),相对于table中检索使用的key,在当前对象存储空间中,对象的该属性值必须唯一,不能重复 | |
* @param {String} accessMode 事务的访问模式,readonly|readwrite|versionchange,默认为readwrite | |
* @returns {Array} 返回查询行为结果的数组 | |
*/ | |
function useIndexedDB(action, dataParam, dbName='testing', version=1, objectStorageName='users', keyPath='userID', accessMode='readwrite') { | |
const result = []; | |
// 创建数据库连接 | |
const request = indexedDB.open(dbName, version); | |
request.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
}; | |
request.onupgradeneeded = function () { | |
const db = request.result; | |
// 创建存储空间 | |
const store = db.createObjectStore(objectStorageName, { keyPath: keyPath }); | |
// const index = store.createIndex('NameIndex', 'username'); | |
}; | |
request.onsuccess = function () { | |
const db = request.result; | |
// 事务 - 读取与修改操作 | |
const transaction = db.transaction(objectStorageName, accessMode); | |
const objectStore = transaction.objectStore(objectStorageName); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
// let i = 0; | |
// // 数据写入 | |
// while(i < users.length) { | |
// const req = objectStore.put(users[i++]); | |
// req.onerror = function (event) { | |
// console.log(event.target); | |
// } | |
// } | |
let newRequest; | |
// getAll() 并不是indexedDB中的标准方法,但在当前的chrome中是可以使用的,是否增加游标查询支持 | |
if (typeof objectStore.getAll === 'function' && action === 'getAll') { | |
newRequest = objectStore.getAll(); | |
} | |
if (action === 'get') { | |
newRequest = objectStore.get(dataParam); | |
} | |
// add(),发现数据库中有一样的键值对象时,会返回一个错误,事务将会终止,可以防止数据被重新添加 | |
// 但没关系,下一次调用dealDataWithIndexedDB()会重新建立一次数据库连接,新建一个新的事务 | |
// 其实,使用put()也没问题,数据有更新就覆盖,没有就相对于重写一遍 | |
// if (action === 'add') { | |
// newRequest = objectStore.add(dataParam); | |
// } | |
if (action === 'add' || action === 'update') { | |
newRequest = objectStore.put(dataParam); | |
} | |
if (action === 'remove') { | |
newRequest = objectStore.delete(dataParam); | |
} | |
if (action === 'removeAll') { | |
newRequest = objectStore.clear(); | |
} | |
newRequest.onerror = function (event) { | |
console.log(event.target); | |
}; | |
newRequest.onsuccess = function (event) { | |
console.log(event.target.result); | |
if (action === 'getAll') { | |
result.push(...newRequest.result); | |
} | |
if (action === 'get') { | |
result.push(newRequest.result); | |
} | |
}; | |
transaction.oncomplete = function () { | |
db.close(); | |
} | |
}; | |
// let dataParam = dealDataWithIndexedDB('getAll'); | |
// !似乎没问题,由于js中对象赋值为浅拷贝,等事件完成后,会往result里push数据对象,相应的更新也会给到dataParam变量。 | |
// 潜在的风险是,数据很多,没来得及把所有数据对象push到result中,而dataParam已经被用于DOM渲染中。 | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// 使用回调函数处理异步操作: | |
// 把依赖于异步操作结果的代码以回调函数的形式传入,并将结果作为回调函数的参数执行回调函数。 | |
// 比如,在todoList项目中,打开应用时,需要获取数据库的所有数据并渲染todoList,将渲染todoList的代码以回调形式传入useIndexedDB()中 | |
// 待写入数据 | |
const users = [ | |
{ | |
userID: '001', | |
username: 'Cherry' | |
}, | |
{ | |
userID: '002', | |
username: 'Rachel' | |
}, | |
{ | |
userID: '003', | |
username: 'Amy' | |
}, | |
{ | |
userID: '004', | |
username: 'Kilo' | |
}, | |
{ | |
userID: '005', | |
username: 'Mia' | |
} | |
]; | |
let result; | |
useIndexedDB('getAll', ''); | |
/** | |
* useIndexedDB() useIndexedDB() 利用indexedDB进行单条数据的增删改查,还支持获取或删除数据库的所有数据 | |
* | |
* @param {String} action 数据库操作行为,getAll|get|add|update|remove|removeAll | |
* @param {String|Object} dataParam 与行为对应的数据参数 | |
* getAll|removeAll 不需要参数, | |
* add|update 需要一个想要新增或更新的数据object, | |
* get|remove 需要一个数据库主值的value | |
* @param {Function} callback 回调函数 | |
* @param {String} dbName 数据库名称,默认为testing | |
* @param {Number} version 数据库版本号,为正整数,默认为1 | |
* @param {String} objectStorageName 对象存储空间名称,相对于SQL的table name,默认为users | |
* @param {String} keyPath 对象存储空间的主值(对象中的属性名称),相对于table中检索使用的key,在当前对象存储空间中,对象的该属性值必须唯一,不能重复 | |
* @param {String} accessMode 事务的访问模式,readonly|readwrite|versionchange,默认为readwrite | |
* @returns {Array} 返回查询行为结果的数组 | |
*/ | |
function useIndexedDB(action, dataParam, callback=saveDataToResult, dbName='testing', version=1, objectStorageName='users', keyPath='userID', accessMode='readwrite') { | |
// const result = []; | |
// 创建数据库连接 | |
const request = indexedDB.open(dbName, version); | |
request.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
}; | |
request.onupgradeneeded = function () { | |
const db = request.result; | |
// 创建存储空间 | |
const store = db.createObjectStore(objectStorageName, { keyPath: keyPath }); | |
// const index = store.createIndex('NameIndex', 'username'); | |
}; | |
request.onsuccess = function () { | |
const db = request.result; | |
// 事务 - 读取与修改操作 | |
const transaction = db.transaction(objectStorageName, accessMode); | |
const objectStore = transaction.objectStore(objectStorageName); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
let i = 0; | |
// 初始数据写入,仅仅是为了IndexedDB中有数据可以操作,实际项目使用时,可以移除 | |
while(i < users.length) { | |
const req = objectStore.put(users[i++]); | |
req.onerror = function (event) { | |
console.log(event.target); | |
} | |
} | |
let newRequest; | |
// getAll() 并不是indexedDB中的标准方法,但在当前的chrome中是可以使用的 | |
if (typeof objectStore.getAll === 'function' && action === 'getAll') { | |
newRequest = objectStore.getAll(); | |
} | |
if (action === 'get') { | |
newRequest = objectStore.get(dataParam); | |
} | |
// add()发现数据库中有一样的键值对象时,会返回一个错误,事务将会终止,可以防止数据被重新添加 | |
// 但没关系,下一次调用dealDataWithIndexedDB()会重新建立一次数据库连接,新建一个新的事务 | |
// 其实使用put()也没问题,数据有更新就覆盖,没有就相对于重写一遍 | |
// 还有一个问题:只要数据对象不是完全一样,主值一样,就可以覆盖原来的数据,add和put都可以 | |
// if (action === 'add') { | |
// newRequest = objectStore.add(dataParam); | |
// } | |
if (action === 'add' || action === 'update') { | |
newRequest = objectStore.put(dataParam); | |
} | |
if (action === 'remove') { | |
newRequest = objectStore.delete(dataParam); | |
} | |
if (action === 'removeAll') { | |
newRequest = objectStore.clear(); | |
} | |
newRequest.onerror = function (event) { | |
console.log(event.target); | |
}; | |
newRequest.onsuccess = function (event) { | |
// console.log(event.target.result); | |
if (typeof callback === 'function') { | |
// 先清空 result 中的的数据,确保之后只包含最新一次操作的数据 | |
result = []; | |
callback(newRequest.result); | |
} | |
}; | |
transaction.oncomplete = function () { | |
db.close(); | |
}; | |
} | |
} | |
function saveDataToResult(data) { | |
if (data !== null) { | |
Array.isArray(data) ? result.push(...data): result.push(data); | |
console.log(result); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// 使用Promise处理异步操作: | |
// 创建一个返回Promise的函数,在Promise的执行器中对需要的最终结果使用resolve(),在代码可能执行失败的地方,使用reject(),“返回”相应的失败信息。 | |
// 把依赖于异步操作结果的代码以回调函数的形式传入then(),并将结果作为回调函数的参数执行回调函数。 | |
// 待写入数据 | |
const users = [ | |
{ | |
userID: '001', | |
username: 'Cherry' | |
}, | |
{ | |
userID: '002', | |
username: 'Rachel' | |
}, | |
{ | |
userID: '003', | |
username: 'Amy' | |
}, | |
{ | |
userID: '004', | |
username: 'Kilo' | |
}, | |
{ | |
userID: '005', | |
username: 'Mia' | |
} | |
]; | |
let result = []; | |
useIndexedDB('getAll', '') | |
.then((query) => { | |
// do something with query result | |
result.push(...query); | |
console.log(result); | |
}) | |
.catch((err) => { | |
console.log(err); | |
}); | |
/** | |
* useIndexedDB() 利用indexedDB进行单条数据的增删改查,还支持获取或删除数据库的所有数据 | |
* | |
* @param {String} action 数据库操作行为,getAll|get|add|update|remove|removeAll | |
* @param {String|Object} dataParam 与行为对应的数据参数 | |
* getAll|removeAll 不需要参数, | |
* add|update 需要一个想要新增或更新的数据object, | |
* get|remove 需要一个数据库主值的value | |
* @returns {Promise<any>} | |
*/ | |
function useIndexedDB(action, dataParam) { | |
return new Promise(function(resolve, reject) { | |
const request = indexedDB.open('testing', 1); | |
request.onerror = function (event) { | |
console.log('Something bad happened while trying to open: ' + event.target.errorCode); | |
reject(event.target); | |
}; | |
request.onupgradeneeded = function () { | |
const db = request.result; | |
// 创建存储空间 | |
const store = db.createObjectStore('users', { keyPath: 'userID' }); | |
// const index = store.createIndex('NameIndex', 'username'); | |
}; | |
request.onsuccess = function () { | |
const db = request.result; | |
// 事务 - 读取与修改操作 | |
const transaction = db.transaction('users', 'readwrite'); | |
const objectStore = transaction.objectStore('users'); | |
transaction.onabort = function (event) { | |
console.log('tx has been aborted.'); | |
console.log(event.target); | |
}; | |
let i = 0; | |
// 初始数据写入,仅仅是为了IndexedDB中有数据可以操作,实际项目使用时,可以移除 | |
while(i < users.length) { | |
const req = objectStore.put(users[i++]); | |
req.onerror = function (event) { | |
console.log(event.target); | |
reject(event.target); | |
} | |
} | |
let newRequest; | |
// getAll() 并不是indexedDB中的标准方法,但在当前的chrome中是可以使用的 | |
if (typeof objectStore.getAll === 'function' && action === 'getAll') { | |
newRequest = objectStore.getAll(); | |
} | |
if (action === 'get') { | |
newRequest = objectStore.get(dataParam); | |
} | |
// add()发现数据库中有一样的键值对象时,会返回一个错误,事务将会终止,可以防止数据被重新添加 | |
// 但没关系,下一次调用dealDataWithIndexedDB()会重新建立一次数据库连接,新建一个新的事务 | |
// 其实,使用put()也没问题,数据有更新就覆盖,没有就相对于重写一遍 | |
// 还有一个问题:只要数据对象不是完全一样,主值一样,就可以覆盖原来的数据,add和put都可以 | |
// if (action === 'add') { | |
// newRequest = objectStore.add(dataParam); | |
// } | |
if (action === 'add' || action === 'update') { | |
newRequest = objectStore.put(dataParam); | |
} | |
if (action === 'remove') { | |
newRequest = objectStore.delete(dataParam); | |
} | |
if (action === 'removeAll') { | |
newRequest = objectStore.clear(); | |
} | |
newRequest.onerror = function (event) { | |
console.log(event.target); | |
}; | |
newRequest.onsuccess = function (event) { | |
// console.log(event.target.result); | |
if (action === 'getAll' || action === 'get') { | |
// result.push(...newRequest.result); | |
resolve(newRequest.result); | |
} | |
}; | |
transaction.oncomplete = function () { | |
db.close(); | |
}; | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment