首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >未捕获的事务:无法读取具有索引数据库的null的属性“TypeError”

未捕获的事务:无法读取具有索引数据库的null的属性“TypeError”
EN

Stack Overflow用户
提问于 2014-06-17 13:18:10
回答 1查看 18.5K关注 0票数 5

当在这段代码中时,我收到错误‘:Cannot read property’TypeError‘of null’

代码语言:javascript
复制
  remoteDB.indexedDB.addAdmins = function() {
           var db = remoteDB.indexedDB.db;
           var trans = db.transaction("students", "readwrite");
           var request = trans.objectStore("administrators");
           /*
          this section edited out since the failure is on line 3
           */
        request.onsuccess = function(e) {

                console.log("success Adding: ", e);
            };


           request.onerror = function(e) {
             console.log(e.value);
           }; 
         };
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-17 20:36:25

remoteDB.indexedDB.db为空。这似乎是一个全局变量引用。为了创建事务,必须定义变量,而不是null和open。

indexedDB是异步的。不能保证当您打开到indexedDB的连接并将该连接的句柄保存在一个全局变量中时,该变量仍然是定义的,而不是null,并在以后从另一个异步函数的上下文中打开。

如果您立即打开一个事务,它有时会起作用。有时,db连接仍然存在。但这并不是有保证的。如果数据库连接上没有打开的事务,则浏览器将在之后的某个时间关闭该连接。

看见

出现这种错误的部分原因通常是程序员对异步javascript不熟悉。这不是批评,这似乎是一种常见的模式。为了避免将来出现错误,我建议花一些时间学习异步javascript。

例如,在尝试使用indexedDB之前,请了解以下内容是如何工作的(或者更确切地说,为什么它不能按预期工作):

代码语言:javascript
复制
var db;
function setDB() {
  db = 123;
}
setTimeout(setDB, 10);
console.log('Got a db variable! %s', db);

要真正做到这一点,在stackoverflow上有成千上万的其他问题以及网上有洞察力的文章和指南是多余的,但这里有一个极端的速成课程。indexedDB.open是一个异步(异步)函数。形容词异步的意思很多。异步函数的行为与同步函数的行为截然不同。新的javascript程序员通常只学会同步编程。因此,你自然不会明白为什么在同步代码中调用异步函数不起作用。同步示例:

代码语言:javascript
复制
var a = 1;
var b = 2;
function sum(arg1, arg2) { return arg1 + arg2 }
var abSum = sum(a,b);
console.log('The sum of a + b is %s', abSum);

您知道,b=2是在a=1之后执行的,sum=a+b是在b之后执行的。这些语句是按您编写的顺序依次执行的。您知道,如果您尝试将第4行放在上面的第1行之前,它将不起作用,因为a和b还没有值。在同步代码中,您知道函数sum返回一个值。它会立即返回它。因此,您知道调用abSum (a,b)会立即将返回值赋给sum。

异步代码的工作方式截然不同。通常,异步函数不会返回所需的值。通常将一个函数(称为回调函数)传递给该函数。异步函数只是在某种程度上保证了它将在稍后调用回调。它不返回要使用的内容。

代码语言:javascript
复制
var a = 1;
var b = 2;
function asyncSum(arg1,arg2,calledWhenFinished) {
  var sum = arg1+arg2;
  calledWhenFinished(sum);
  return 'asyncSumFinished and called the callback';
}

// The following DOES NOT work as expected
var theResultOfSum = asyncSum(a,b, function(sum) {
 console.log('finished. The um is %s', theResultOfSum);
});

// The following DOES work as expected
asyncSum(a,b, function(sum) {
 console.log('The sum is %s', sum);
});

请注意,在工作示例中,我并不关心asyncSum返回什么。毕竟,它并不返回sum,它只是返回一个字符串,说明它已经完成了。现在,让我们做一些更真实的异步操作。

代码语言:javascript
复制
function moreGenuineAsyncSum(a,b, callback) {
  setTimeout(function() {
    var sum = a + b;
    console.log('The sum is %s', sum);
    callback(sum);
  }, 100);
  console.log('Requested the sum to be calculated');
  return 'Hey, I scheduled the callback function to execute in 100ms';
}

在这里,我真的不关心moreGenuineAsyncSum的返回值。事实上,它一文不值。它只是一个能表达某些东西的字符串。还要注意哪个console.log调用首先被执行。后一行在前一行之前执行。杂乱无序。打乱了它的书写顺序。为什么会这样呢?因为这就是异步函数所做的,所以它们会在以后的某个时间点执行某些操作。

indexedDB.open是一个异步函数。它返回一个IDBOpenRequest对象,这是一种请求对象。大多数indexedDB函数都是异步的,并且返回请求对象。请求对象没有值。它们将回调作为属性。因此:

代码语言:javascript
复制
var dbRequest = indexedDB.open('mydb',1);
dbRequest.onsuccess = function(event) {
  // This gets called later. The following are all viable ways to get the IDBDatabase
  // object INSIDE THE BLOCK OF THIS FUNCTION ONLY. Any one of the following 3 lines
  // works exactly the same way.
  var db = this.result;
  var db = dbRequest.result;
  var db = event.target.result;

  console.log('Got a db connection! It is %s', db);

  // Now, INSIDE THE BLOCK OF THIS FUNCTION ONLY, do something:
  var myTransaction = db.transaction('myObjectStore','readwrite');
  var myObjectStore = myTransaction.objectStore('myObjectStore');

  // etc.
};

在我写整本书之前总结一下,重点放在上面的块注释里面。在块内部,保证'db‘变量在那里,并且是开放的,并且是被定义的,并且不为空。在块之外,db变量不存在。

所以你可能会说,这使得使用indexedDB非常烦人。你说得对,这很烦人。为了让它对你不那么烦人,你可以学习promises。或者你可以像函数一样编写回调函数。或者,您可以使用处理回调地狱的无数设计模式中的一个。有很多。一种是使用像EventTarget这样的模式及其与DOM的关系。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24256202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档