繁体   English   中英

indexedDB中的“无法调用未定义的方法'事务'”错误

[英]“Cannot call method 'transaction' of undefined” error in indexedDB

下面是我的代码。 第一次运行正常,但是一旦刷新页面,它将生成未捕获的TypeError:无法调用未定义的方法“事务”。

基本上,我从数据库中检索数据并将其编码为可用的JSON数据类型,以避免在表中插入问题。

$(document).ready( function() {

//prefixes of implementation that we want to test
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;

//prefixes of window.IDB objects
window.IDBTransaction = window.IDBTransaction ||
                        window.webkitIDBTransaction ||
                        window.msIDBTransaction;

window.IDBKeyRange = window.IDBKeyRange ||
                     window.webkitIDBKeyRange ||
                     window.msIDBKeyRange

if(!window.indexedDB){ //alert user if browser does not support
    window.alert("Your browser doesn't support a stable version of IndexedDB.")
}

var request = window.indexedDB.open("runningClub", 1); //create a runningClub database

var browserDB;

request.onsuccess = function(event){
    browserDB = request.result;
};

var raceIDs = [];

$(".raceID").each( function () {
    raceIDs.push(" raceID = " + $(this).val());
});

$.ajax({
    url: 'controller/AJAX/userAction.php',
    type: 'post',
    dataType: 'json',
    data: { statement : "getRaceResult", raceIDs : raceIDs },
    success: function(data) {

        const results = data;

        request.onupgradeneeded = function(event){
            var browserDB = event.target.result;
            var objectStore = browserDB.createObjectStore("raceResult", {keyPath: "resultID"});
            for(var i in results){
                objectStore.add(results[i]);       
            }
        }

        var objectStore = browserDB.transaction("raceResult").objectStore("raceResult");

        objectStore.openCursor().onsuccess = function(event){
            var cursor = event.target.result;
            if (cursor){
                $("#memberName").append("<option>" + cursor.value.memberName + "</option>");
                cursor.continue();
            }
        };
    }
});
});

感谢您发布(几乎)完整的代码。 不幸的是,如果不知道来自后端的数据对象的结构,我将无法完全复制您的问题。 介意发布吗?

也就是说,我可以肯定您的问题是使用const

const results = data;

我不认为这种类型的数据可以“ 结构化克隆 ”。 鉴于JSON是完全可克隆的,这是我想从您的API中返回的(相对于例如可以通过赋值产生function JavaScript),因此使用此关键字似乎是造成问题的罪魁祸首。

更新1解决了这个问题,异步编程存在很多问题。

  • 数据库在ajax请求之前打开,而不是在成功回调之后打开。 将其移到回调中似乎很谨慎。
  • browserDBsuccess回调中定义,该回调不能保证在异步操作完成之前运行(因此browserDB变为未定义)
  • request.onsuccess被调用两次(你可能没有意识到这一点,因为它的怪异行为):既当没有upgradeneeded事件触发,当一个upgradeneeded事件触发,所以你重新定义browserDB有意无意DB时,还不存在

更新2这是一个最有效的简化Fiddle 我为花多少时间使代码工作而感到难过。

更多问题(除了const之外):

  • 硬编码的数据库版本
  • 重复使用versionchange事件来添加/获取数据是一个坏主意
  • 需要使用readwrite事务来添加数据
  • openCursor-但不为resultID键路径提供参数
  • 您在获取数据之前没有在听成功的添加
  • 您没有在获取数据之前将成功事件链接到添加项

当前的循环方法是站不住脚的。 但是我通过单个添加和一个游标get使其工作。 您可以将其重构为多次添加的方法,但是您需要观看异步消息(根据我的观察,我建议您坚持简单的做法)。

$.ajax({
  url: '/echo/json/',
  type: 'post',
  dataType: 'json',
  data: {
    json: JSON.stringify({
      resultID: new Date().getTime(),
      raceID: "1",
      memberID: "824",
      runtime: "00:31:26",
      memberName‌: "Mark Hudspith"
    })
  },
  success: function (data) {
    var request,
      upgrade = false,
      doTx = function (db, entry) {
        addData(db, entry, function () {
          getData(db);
        });
      },
      getData = function (db) {
        db.transaction(["raceResult"], "readonly").objectStore("raceResult").openCursor(IDBKeyRange.lowerBound("0")).onsuccess = function (event) {
          var cursor = event.target.result;
          if (null !== cursor) {
            console.log("YOUR DATA IS HERE", cursor.value.memberName‌);
            cursor.continue();
          }
        };
      },
      addData = function (db, entry, finished) {
        var tx = db.transaction(["raceResult"], "readwrite");
        tx.addEventListener('complete', function (e) {
          finished();
        });
        tx.objectStore("raceResult").add(entry);
      };
    request = window.indexedDB.open("runningClub");
    request.onsuccess = function (event) {
      if (!upgrade) {
        doTx(request.result, data);
      }
    };
    request.onupgradeneeded = function (event) {
      var db = event.target.result;
      db.createObjectStore("raceResult", {
        keyPath: "resultID"
      });
      setTimeout(function () {
        doTx(db, data);
      }, 5000);
    }
  }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM