Javascript &引用;无法调用方法';交易';“未定义”的定义;indexedDB中的错误

Javascript &引用;无法调用方法';交易';“未定义”的定义;indexedDB中的错误,javascript,indexeddb,Javascript,Indexeddb,下面是我的代码。它第一次运行正常,但一旦我刷新页面,它就会生成一个未捕获的TypeError:无法调用undefined的方法“transaction” 基本上,我从数据库中检索数据,并将其编码为可用的JSON数据类型,以避免在表中插入问题 $(document).ready( function() { //prefixes of implementation that we want to test window.indexedDB = window.indexedDB ||

下面是我的代码。它第一次运行正常,但一旦我刷新页面,它就会生成一个未捕获的TypeError:无法调用undefined的方法“transaction”

基本上,我从数据库中检索数据,并将其编码为可用的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();
            }
        };
    }
});
});
$(文档).ready(函数(){
//我们要测试的实现的前缀
window.indexedDB=window.indexedDB||
window.mozindexedb||
window.webkitIndexedDB||
window.msIndexedDB;
//window.IDB对象的前缀
window.IDBTransaction=window.IDBTransaction||
window.webkitIDBTransaction||
window.msIDBTransaction;
window.IDBKeyRange=window.IDBKeyRange||
window.webkitIDBKeyRange||
window.msIDBKeyRange
如果(!window.indexedDB){//如果浏览器不支持
警告(“您的浏览器不支持IndexedDB的稳定版本。”)
}
var request=window.indexedDB.open(“runningClub”,1);//创建runningClub数据库
var-browserDB;
request.onsuccess=函数(事件){
browserDB=request.result;
};
变异外消旋体=[];
$(“.raceID”)。每个(函数(){
raceIDs.push(“raceID=”+$(this.val());
});
$.ajax({
url:'controller/AJAX/userAction.php',
键入:“post”,
数据类型:“json”,
数据:{语句:“getRaceResult”,raceIDs:raceIDs},
成功:功能(数据){
常量结果=数据;
request.onupgradeneeded=函数(事件){
var browserDB=event.target.result;
var objectStore=browserDB.createObjectStore(“racesult”,{keyPath:“resultID”});
对于(结果中的var i){
objectStore.add(结果[i]);
}
}
var objectStore=browserDB.transaction(“racesult”).objectStore(“racesult”);
objectStore.openCursor().onsuccess=函数(事件){
var cursor=event.target.result;
如果(光标){
$(“#memberName”).append(“+cursor.value.memberName+”);
cursor.continue();
}
};
}
});
});
感谢您发布(几乎)全部代码。不幸的是,如果不知道来自后端的数据对象的结构,我无法完全复制您的问题。介意把它也公布出来吗

也就是说,我相当确定您的问题是
const
的使用

const results = data;
我不相信这类数据是“可以”的。考虑到JSON是完全可克隆的,这就是我想象中从API返回的内容(与JavaScript相比,JavaScript可以生成
函数
),这个关键字的使用似乎是问题的罪魁祸首

更新1解决异步编程中的许多问题

  • 数据库在ajax请求之前打开,而不是在成功回调之后打开。将此移到回调中似乎很谨慎
  • browserDB
    success
    回调中定义,该回调不保证在异步操作完成之前运行(因此
    browserDB
    变得未定义)
  • request.onsuccess
    被调用了两次(您可能没有意识到这一点,因为这是一种奇怪的行为):无论是在无
    upgradeneeded
    事件触发时,还是在
    upgradeneeded
    事件触发时,您都在重新定义
    browserDB
    ,可能是在DB还不存在的情况下意外发生的
更新2这里有一个最有效的方法。我很难过我花了多少时间让你的代码工作

更多问题(超出常量)

  • 硬编码数据库版本
  • 重用
    versionchange
    事件来添加/获取数据是个坏主意
  • 需要使用
    readwrite
    事务添加数据
  • openCursor-但不为resultID键路径提供参数
  • 在获取数据之前,您没有侦听成功的添加
  • 在获取数据之前,您没有为添加链接成功事件
目前的循环方法是站不住脚的。但是我用一个add和一个cursorget来实现它。您可以重构回多个add方法,但需要注意异步(根据我所看到的,我建议您坚持使用simple)


后端是这样的:案例'getRaceResult':$raceResults=$user->getAllRaceResult($RaceId);echo json_encode($racesults);打破粘贴失败,但删除了“const”关键字,替换为
var
,并为我试一试。PHP,很酷,我完全同意-但我需要
$racesults
的值。我要做的是确认您的数据是可存储的。IDB无法存储所有类型的JavaScript数据。返回数据之一是:[{“resultID”:“1”,“raceID”:“1”,“memberID”:“824”,“runtime”:“00:31:26”,“memberName”:“Mark Hudspith”}]感谢您的努力
$.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);
    }
  }
});