7

当 IndexedDB 事务完成或成功时,我使用两个不同的回调事件来响应:

假设... db:IDBDatabase 对象,tr:IDBTransaction 对象,os:IDBObjectStore 对象

tr = db.transaction(os_name,'readwrite');
os = tr.objectStore();

情况1 :

r = os.openCursor();
r.onsuccess = function(){
    if(r.result){
        callback_for_result_fetched();
        r.result.continue;
    }else callback_for_transaction_finish();
}

案例2:

tr.oncomplete = callback_for_transaction_finish();

如果他们两个工作相似,那就太浪费了。那你能告诉我,它们之间有什么区别吗?

4

3 回答 3

9

很抱歉提出了一个相当老的线程,但它的质疑是一个很好的起点......

我寻找了一个类似的问题,但在一个有点不同的用例中,实际上没有找到好的答案,甚至没有找到误导性的答案。

当您需要对objectStore进行多次写入时,请考虑一个用例,甚至写入多次。您绝对不想管理每一次写入以及它自己的成功和错误事件。这就是事务的含义,这是 indexedDB 的(正确)实现:

var trx = dbInstance.transaction([storeIdA, storeIdB], 'readwrite'),
    storeA = trx.objectStore(storeIdA),
    storeB = trx.objectStore(storeIdB);

    trx.oncomplete = function(event) {
        // this code will run only when ALL of the following requests are succeed
        // and only AFTER ALL of them were processed
    };
    trx.onerror = function(error) {
        // this code will run if ANY of the following requests will fail
        // and only AFTER ALL of them were processed
    };

    storeA.put({ key:keyA, value:valueA });
    storeA.put({ key:keyB, value:valueB });
    storeB.put({ key:keyA, value:valueA });
    storeB.put({ key:keyB, value:valueB });

这种理解的线索可以在 W3C规范的以下声明中找到:

要确定事务是否成功完成,请侦听事务的完成事件而不是特定请求的成功事件,因为在成功事件触发后事务仍可能失败。

于 2014-04-14T08:11:25.313 回答
8

虽然这些回调函数确实类似,但它们并不相同:和之间的区别在于,在这些事务上发出的事务onsuccess和请求是.oncompletecompletesuccessful

oncomplete仅在规范中定义为与事务相关。事务没有onsuccess回调。

于 2012-06-22T02:37:07.750 回答
2

我只会警告说,没有 garentee 获得成功的 trx.oncomplete 意味着数据已写入磁盘/数据库:

我们看到 trx.oncomplete 存在数据未写入磁盘上的数据库的问题。FireFox 解释了他们所做的导致此问题的原因:https ://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

似乎 windows/edge 也有同样的问题。基本上,如果/当用户决定关闭或关闭设备时,不能保证您的应用程序会将数据写入数据库。在某些情况下,我们甚至尝试在关闭之前等待长达 15 分钟,但还没有看到写入的数据。对我来说,我总是希望确保数据写入完成并提交。

除了 FF 实验性添加之外,还有其他针对真正持久数据库的解决方案,或者对 IndexedDB 的增强...

于 2016-10-19T15:21:44.483 回答