html离线存储之indexdDB 关于Cannot read property 'transaction' of undefined的问题(二)

来源:互联网 发布:遗传算法在液压系统 编辑:程序博客网 时间:2024/05/16 09:41

IndexedDB标准是HTML5官方认可的本地数据库解决方案。而webSQL已经被w3c抛弃了。

这里我主要说下我遇到的问题,这两天才开始捣鼓这一块,想边学边写好一些接口,方便日后使用参考。但在写插入功能的时候卡住了。


我已经写了创建数据库的接口,并执行正常

//新建或打开数据库,第一次创建或更改版本时建表
//dbname:数据库名;version:版本号;storeName:仓库名;key:索引;increment:是否自增function initIndexdDB(dbname,version,storeName,key,increment=false){var indexdDB = window.indexdDB||window.webkitIndexdDB||window.mozIndexdDB||window.msIndexdDB;var request = indexedDB.open(dbname, version);// var database=null;request.onsuccess = function(event) {        console.log("创建/打开数据库成功。");         //让数据库 可在任何地方访问        database = request.result;        //console.log("init"+database);    };    request.onerror = function (event) {        console.log("发生错误:" + request.error);    };    request.onupgradeneeded = function(event) {        alert("第一次创建数据库或者更新数据库。");        //alert("数据库老版本为:" + event.oldVersion + " 更新后新版本为:" + event.newVersion)    database = request.result;    if(!increment)    var objectStore = database.createObjectStore(storeName, { keyPath: key });     else    var objectStore = database.createObjectStore(storeName, { keyPath: key ,autoIncrement: true});     };}

上面的接口可以用于打开已有数据库,创建数据库不建表或者并建表,打开指定数据库并建表。

本人在向已有数据库中建表这里,饶了不少圈子,这里说下,避免刚入坑者少踩坑,关键是理解好onupgradeneeded,它是在初次创建或者版本号发生更改的时候会被触发的时候执行,而建表的操作是放在这里面执行的,因为只要数据库的版本号没变,就可以算是表示数据库未发生变化,自然是无法在别处新建表的


接着说下又一个坑点,就是插入数据了,我写的接口是这样的
//增加记录//objectStore:仓库(表)名,method(操作方式),objectData(插入的对象)function addRecord(objectStore,method,objectData) {// console.log(database); var transaction = database.transaction([objectStore], method);var objectStore = transaction.objectStore(objectStore);var request = objectStore.put(objectData);request.onerror = function(event) {console.log("发生错误:" + request.error);};request.onsuccess = function(event) {console.log("添加成功");}; }
其中database为打开的数据库对象,为全局变量,为什么不能将其设置为参数呢,我开始就是这么干的,然后在控制台就一直出现文章标题中的Cannot read property 'transaction' of undefined,百度了下只在StackOverflow中看到有个在解释的,大体上说的是indexdDB异步执行的原因,我自己也不是很理解这块,就各种console.log(),发现当将其设置为参数时,即使database为全局变量,且在initIndexdDB中已经将其赋值为数据库对象,但console.log的结果仍然是null


如上图所示,database为null,自然后面的插入数据操作会失败,但从上图也可以看出问题得一些端倪,控制台上是先执行了console.log(),后才打开了数据库并赋值给了database,这里也看出indexdDB是异步执行的

所以下图这样效果就是对的了



我这里因为都是控制台操作,可以一步步来,当把一组操作代码写好一起执行时就要格外注意这里了,代码执行速度很快还来不及获取到异步赋值的 database。理解好这个插入数据就不难了


0 0
原创粉丝点击