IndexedDB如何确保在事件发生之前添加IDBOpenDBRequest.onupgradeneeded

时间:2018-11-26 23:49:50

标签: javascript indexeddb

几个IndexedDB文档说明了初始化数据库和创建一个ObjectStore的以下顺序。

1) request = window.indexedDB.open(...)
2) request.onsuccess = ...;
3) request.onupgradeneeded = ...

但是我发现如果步骤(3)在一段时间后完成,则不会执行。

这是测试代码:

var db;
var request = window.indexedDB.open("birds-db", 1);
const startTime = new Date().getTime();
const simulatedDelay = 300;

function deltaTime() {
    return new Date().getTime() - startTime;
}

request.onerror = function(event) {
    console.log('error: ' + event);
};

request.onsuccess = function(event) {
    console.log('onsuccess was called T' + deltaTime());
    db = event.target.result;
};

setTimeout(function() {
    console.log('after waiting  ' + simulatedDelay + " miliseconds T" + deltaTime());
    request.onupgradeneeded = function(event) {
        console.log('onupgradeneeded was called T' + deltaTime());
        var db = event.target.result;
        var objectStore = db.createObjectStore("birds", {
            keyPath: "sci_name"
        });
    };
}, simulatedDelay);

console.log("end " + deltaTime());

在上面的示例中,如果将SimulationDelay设置为300毫秒,则大多数情况下效果会很好,显示如下内容:

end 1
after waiting  300 miliseconds T302
onupgradeneeded was called T474 
onsuccess was called T479

但是将其设置为2000或更高将导致:

end 0
onsuccess was called T602
after waiting  2000 miliseconds T2001

“ onupgradeneeded”根本没有被调用。我的浏览器是Firefox 60。

当然,如果我在“打开”之后立即设置“ onupgradeneeded”,则不会发生此问题。

如何确定在更复杂的情况下总是在事件发生之前设置onupgradeneed?

1 个答案:

答案 0 :(得分:2)

除非您同步设置事件处理程序,否则这是竞争条件。如果在事件触发之前设置了事件处理程序,则使用回调函数。否则,不会。

实际上,由于争用条件非常混乱,您应该始终同步设置这些事件处理程序。