Indexeddb:onsuccess和oncomplete之间的差异?

时间:2012-06-22 02:14:24

标签: database indexeddb

当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();

如果两者的工作方式类似,那将是一种浪费。所以你能告诉我,它们之间有什么区别吗?

3 个答案:

答案 0 :(得分:8)

虽然这些回调的功能类似,但它们并不相同:onsuccessoncomplete之间的区别在于事务complete,而在这些事务上发出的请求是{ {1}}。

successful仅在the spec中定义为与交易相关。交易没有oncomplete回调。

答案 1 :(得分:8)

很抱歉提出了一个很老的话题,但它的质疑是一个很好的起点...

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

当你需要将多次写入写入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 spec的以下声明中可以找到这种理解的线索:

  

要确定交易是否已成功完成,请收听交易的完成事件而非特定请求的成功事件,因为在成功事件触发后交易仍可能失败。

答案 2 :(得分:2)

我只是提醒说,没有成功获得成功的trx.oncomplete意味着数据被写入磁盘/数据库:

我们发现trx.oncomplete存在问题,其中数据未写入磁盘上的数据库。 FireFox在这里解释了他们所做的导致此问题:https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

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

是否存在真正持久性数据库的其他解决方案,或者除了FF实验添加之外的IndexedDB的增强...