【问题标题】:How to loop through indexedDB tables synchronously?如何同步循环遍历 indexedDB 表?
【发布时间】:2012-08-23 12:56:02
【问题描述】:

我想在 JS 中编写一个函数,我将在我的索引数据库中循环遍历一个表,并获取最后修改的表的最大值并返回该值

function readData(){
    var trans = '';
    trans = idb.transaction(["tableName"],'readonly'); // Create the transaction
    var request = trans.objectStore("tableName").openCursor();
    request.onsuccess = function(e) {
        var cursor = request.result || e.result; 
        if(cursor) {
            // logic to  and find maximum
        } else {
            return // max last modified
        }
        cursor.continue();
    }
}

IMP--既然 onsuccess 方法是异步的,我怎样才能让它同步呢?这样我的方法 readData() 将仅在成功找到最大最后修改记录时返回。如果需要,我可以同步调用这个方法(readData())来获取2-3个表的最后修改记录。

【问题讨论】:

    标签: html indexeddb


    【解决方案1】:

    同步 API 仅在 webworker 中可用。所以这将是第一个要求。 (据我所知目前只有 IE10 支持)

    您可以提供的另一个方法是使用 JS 1.7 并使用 yield 关键字。有关它的更多信息,请查看here

    我建议使用您在达到最新值时调用的 callbakck 方法。

    function readData(callback){     
       var trans = '';         
       trans = idb.transaction(["tableName"],'readonly'); //Create the transaction   
       var request = trans.objectStore("tableName").openCursor();
       var maxKey;      
       request.onsuccess = function(e) {   
           var cursor = request.result || e.result;             
           if(cursor.value){             
              //logic to  and find maximum
              maxKey = cursor.primaryKey            
              cursor.continue();
           }
       } 
       trans.oncomplete = function(e) {
            callback(maxKey); 
       }
    } 
    

    【讨论】:

    • 没有浏览器实现同步 API,即使在 web worker 中也是如此。 AFAIK,只有 chrome 完全支持 web worker 中的 indexeddb,而这只是异步 API。
    • 这不起作用,因为变量 maxKey 在游标上的成功事件中声明,每次在游标继续时调用。我已经提交了对您的代码的修改,请查看它。
    • 为什么不使用var request = trans.objectStore("tableName").openCursor(null, 'prev');的键范围第一个结果将是最后插入的键。
    • 正确,但您仍然需要迭代每一条记录。所以这样不会有太大的不同
    【解决方案2】:

    顶部框架中的 IndexedDB API 是异步的。 async 不能是同步的。但是您可以在单个事务中读取所有表。

    【讨论】:

    • 如何在单个事务中读取所有表?请发布一个例子..我会很感激..
    • 为所有商店打开transdb.transaction(db.objectStoreNames, IDBTransaction.readonly),通过重复打开商店读取数据trans.objectStore(db.objectStoreNames[i]).openCursor()trans 直到你完成后才会提交。只要您在事务中同步运行它就应该可以工作,我没有尝试过。
    猜你喜欢
    • 2023-03-26
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2018-07-21
    • 1970-01-01
    • 2016-08-06
    相关资源
    最近更新 更多