【问题标题】:indexedDB correct usageindexedDB 正确用法
【发布时间】:2014-09-23 19:53:23
【问题描述】:

我正在试验 indexedDB。现在一切都像异步一样,这对我的大脑造成了很大的伤害。

我创建了一个这样的对象:

var application = {};
application.indexedDB = {};
application.indexedDB.db = null;

application.indexedDB.open = function() {

   var dbName = "application";
   var dbVersion = 1;

   var openRequest = indexedDB.open(dbName, dbVersion);

   openRequest.onupgradeneeded = function(e) {

      console.log("Upgrading your DB (" + dbName + ", v" + dbVersion + ")...");

      var thisDB = e.target.result;

      if (!thisDB.objectStoreNames.contains("journal")) {
         thisDB.createObjectStore(
            "journal", 
            {keyPath: "id"}
         );
      }
   }

   openRequest.onsuccess = function(e) {
      console.log("Opened DB (" + dbName + ", v" + dbVersion + ")");
      application.indexedDB.db = e.target.result;
   }

   openRequest.onerror = function(e) {
      console.log("Error");
      console.dir(e);
   }
};

现在我可以使用application.indexedDB.open() 打开数据库连接。现在我向我的对象添加了另一个函数:

application.indexedDB.addItemToTable = function(item, table) {

    var transaction = application.indexedDB.db.transaction([table], "readwrite");
    var store = transaction.objectStore(table);

    //Perform the add
    var request = store.add(item);

    request.onerror = function(e) {
        console.log("Error", e.target.error.name);
        //some type of error handler
    }

    request.onsuccess = function(e) {
        console.log("Woot! Did it");
    }
};

我的指令序列扩展如下:

  1. application.indexedDB.open()
  2. application.indexedDB.addItemToTable(item, "journal")

但这不起作用。因为 open-Instruction 是异步的,所以当我在 addItemToTable-Function 中调用它时,application.indexedDB.db 还不可用。 Javascript 开发人员如何解决这个问题?

我在这里学习本教程:http://code.tutsplus.com/tutorials/working-with-indexeddb--net-34673,现在我对这些示例有一些问题。

例如,他直接在“onsuccess”部分(在“阅读更多数据”部分)中创建 HTML 输出。在我看来,这是不好的编码,因为视图与 db-reading 部分无关。不是吗?但接下来是我的问题。你怎么能在“onsuccess”部分返回一些东西? 添加回调函数有点复杂。特别是当我想读取一些数据并使用该结果集获取更多数据时。描述我的意思非常复杂。 我做了一个小小提琴 - 也许它澄清了一些事情.. -- http://jsfiddle.net/kb8nuby6/

谢谢

【问题讨论】:

  • 仅供参考,有一个名为 IDBWrapper 的库,它封装了复杂性并提供了一种处理 IndexedDb 的便捷方法。了解更多:jensarps.github.io/IDBWrapper
  • 我会推荐一个在 indexDB 之上使用的工具,这样您就不必处理那么多低级编码。 pouchDB 是一个很好的,甚至是 jQeury。您还可以考虑创建允许您以更传统的自上而下方式编写代码的 Promise 包装器。
  • ConstraintError 表示您正在尝试使用现有密钥添加数据。尝试重命名您的数据库,它不会给您任何错误
  • 感谢您的 cmets!您建议的框架(pouchDB 和 IDBWrapper)看起来很有前途。我会尽快检查出来!正如@Josh 在他的帖子中所说 - 我将练习异步 js .. 那里似乎缺乏知识.. :)

标签: javascript indexeddb


【解决方案1】:

您不需要使用其他人的额外程序。在使用 indexedDB 之前,您需要了解异步 javascript (AJAX)。没有办法避免它。无需了解 indexedDB 即可了解 AJAX。例如,看看 XMLHttpRequest 是如何工作的。了解 setTimeout 和 setInterval。也许了解 requestAnimationFrame。如果你知道 nodejs 的东西,请查看 process.nextTick。了解函数如何是一流的。了解使用回调函数的想法。了解延续传递风格。

你可能不会得到你正在寻找的这个问题的答案。如果有的话,这是与 javascript 中有关异步编程的堆栈溢出的数千个其他问题的重复。它甚至与 indexedDB 无关。看看关于异步 js 的许多其他问题。

也许这会让你开始:

var a;
setTimeout(function() { a = 1; }, 10);
console.log('The value of a is %s', a);

找出为什么这不起作用。如果你这样做了,你将更接近于找到这个问题的答案。

【讨论】:

    【解决方案2】:

    我常用的模式是等待所有数据库操作直到连接。它类似于 jQuery 中的$.ready 概念。

    您会发现随着应用程序的老化,您有许多架构版本,并且也需要升级数据。数据库连接本身有很多逻辑。

    如果您需要在准备好之前使用数据库,您可以使用回调队列。这是来自 Google Analytics 的 sn-p commend queue

    // Creates an initial ga() function.  The queued commands will be executed once analytics.js loads.
    i[r] = i[r] || function() {
      (i[r].q = i[r].q || []).push(arguments)
    },
    

    基本上,一旦数据库连接,您将执行这些回调。

    我强烈建议查看我自己的库 ydn-db。它包含所有这些概念。

    【讨论】:

      猜你喜欢
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 2012-03-08
      • 2011-07-25
      • 1970-01-01
      • 2011-02-10
      • 2021-10-16
      相关资源
      最近更新 更多