如何检查 IndexedDB 实例是否已打开?

6
假设我有一个indexedDB对象的实例。是否有一种简单的方法来检测对象是否处于“打开”状态?
我尝试过database.closePending和查看其他属性,但没有看到告诉我数据库状态的简单属性。
我想同步地做到这一点。
像尝试在数据库上打开事务并检查是否发生异常这样的操作对我来说不是一个合理的解决方案。
我不想维护与数据库实例相关联的额外变量。
也许我错过了api中的一些简单功能吗?是否有某些可观察的实例变量特性,可以快速轻松地查询以确定状态?
换句话说,您能否改进以下实现?
function isOpen(db) {
  if(db && Object.prototype.toString.call(db) === '[object IDBDatabase]') {
    var names = db.objectStoreNames();
    if(names && names.length) {
      try {
        var transaction = db.transaction(names[0]);
        transaction.abort();
        return true;
      } catch(error) {
      }
    }
  }
}

还是这种方法?

var opened = false;
var db;
var request = indexedDB.open(...);
request.onsuccess = function() {
  db = request.result;
  opened = true;
};

function isOpen(db) {
  return opened;
}

db.close();
opened = false;

或者用这种方法?
var db;
var request = indexedDB.open(...);
request.onsuccess = function() {
  db = request.result;
  db.onclose = function() {
    db._secret_did_close = true;
  };
};

function isOpen(db) {
  return db instanceof IDBDatabase && !db.hasOwnProperty('_secret_did_close');
}

抱歉耽误您的时间,但我看了代码后更喜欢中间部分,因为您不需要检查所有内容,只需使用事件和回调即可获得错误。您可以在浏览器控制台上显示它,并通过测试“发生了什么”来制造一些错误。我认为好的方法是在事务期间实现所有方法,其中大多数错误都存储在其中。连接仍然可以运行,并且您可以通过使用阻止事件来捕获此事件...这就是为什么只需实现并添加一个console.log以确保的原因。 - user8556290
2个回答

3

API中没有其他内容可以告诉你连接是否关闭。你列举的可能性是唯一可用的。

此外,API中没有closePending属性。规范文本使用一个close pending标志来表示内部状态,但这不会暴露给脚本。

尝试在数据库上打开事务并检查是否发生异常之类的操作对我来说不是合理的解决方案。

为什么?这是最可靠的方法。维护额外的状态无法应对意外的关闭(例如用户删除浏览数据,强制关闭连接),尽管这是onclose处理程序所能应对的-您需要结合第二种和第三种方法。(如果通过脚本调用close(),则不会触发close)。


谢谢Josh。不过我很想看到这样的功能!我的用例是在开始新事务之前进行防御性开发阶段断言。 - Josh

0
你应该使用 indexedDB.open 创建一个 request,如果连接打开了,你就会跳转到 onsuccess 方法。
request = indexedDB.open('html5',1);

request.onsuccess = function() {
    console.log('Database connected');
};

例子:

https://codepen.io/headmax/pen/BmaOMR?editors=1111

关于如何关闭或者如何知道indexedDB是否仍然打开:我猜你需要在每个事务上实现所有事件:例如,为了控制,你可以使用事件:transaction.onerror、transaction.onabort等。如果你需要一些示例解释,我想你需要创建一个新的帖子 ;)。

https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction


抱歉如果我表达不清楚,但这与我的问题无关。我已经使用这种方法打开了数据库的实例。现在我想能够检查该实例并查看它是否仍然处于打开状态,而且是在很长一段时间之后。 - Josh
@Josh,如果你知道在方法中,任务可以通过手动使用event.target.close();来关闭,如果你想关闭数据库,只需执行db.close();,如果我理解问题的话? - user8556290
1
抱歉,但这与我所问的完全无关。我已经编辑了问题,试图更清楚地表达。 - Josh
没问题,Josh,我理解。 - user8556290

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接