Запуск кода только после обновления объекта в IndexedDB (особенно в Chrome)

Я чувствую, что это довольно обыденная вещь. Я хочу обновить объект в базе данных IndexedDB, а затем запустить некоторый код, после которого используются обновленные значения.

То, что я первоначально сделал, это просто запустил мою функцию обратного вызова после вызоваcursor.update, который работает в Firefox. Но в Chrome происходит сбой, обновление не происходит до запуска следующего кода. Это, скорее всего, условие гонки, поскольку (насколько я понимаю) обновления являются асинхронными.

Итак, я подумал, что я должен использоватьonsuccess сигнал оcursor.update чтобы вызвать мою функцию обратного вызова. Но, к моему большому удивлению, в Chrome это тоже не работает!

Пример кода, которыйвы можете запустить на jsFiddle ... хотя забавно, что по какой-то причине в Firefox происходит сбой в jsFiddle, но Chrome работает нормально; для Firefox вы можете запустить его локально, и он работает (это выводит на консоль JavaScript в вашем браузере):

<html>
<head>
<script>
var db, request;

request = indexedDB.open("test", 1);
request.onupgradeneeded = function (event) {
    var i, leagueStore, teams, teamStore;

    db = event.target.result;

    objectStore = db.createObjectStore("objects", {keyPath: "id"});
};
request.onsuccess = function (event) {
    db = request.result;

    // Add some dummy data
    db.transaction("objects", "readwrite").objectStore("objects").put({
        id: 0,
        value: 42
    });

    // Update data
    db.transaction("objects", "readwrite").objectStore("objects").openCursor(0).onsuccess = function (event) {
        var cursor, object;

        cursor = event.target.result;
        object = cursor.value;
        object.value = 43;
        cursor.update(object).onsuccess = function (event) {
            db.transaction("objects").objectStore("objects").get(0).onsuccess = function (event) {
                console.log("Cursor update onsuccess event:");
                console.log(event.target.result);
            };
        };

        // Read back updated data
        db.transaction("objects").objectStore("objects").get(0).onsuccess = function (event) {
            console.log("The line after the cursor update:");
            console.log(event.target.result);
        };

        // Wait a little bit, then read it back
        setTimeout(function () {
            db.transaction("objects").objectStore("objects").get(0).onsuccess = function (event) {
                console.log("After an additional delay via setTimeout:");
                console.log(event.target.result);
            };
        }, 100);
    };
};
</script>
</head>
</html>

Наблюдаемое поведение (все в Ubuntu 12.10, FWIW):

В Firefox 19 (текущая стабильная версия) все три зарегистрированных объекта идентичны, сvalue установить на 43:

The line after the cursor update:
Object {id: 0, value: 43}
Cursor update onsuccess event:
Object {id: 0, value: 43}
After an additional delay via setTimeout:
Object {id: 0, value: 43}

В Chrome 25 (текущая стабильная версия) и 27 (текущая нестабильная версия) я обычно получаю такой вывод:

The line after the cursor update:
Object {id: 0, value: 42}
Cursor update onsuccess event:
Object {id: 0, value: 42}
After an additional delay via setTimeout:
Object {id: 0, value: 43}

Иногда один из первых двух выходов обновляется до 43, но обычно это 42.

Итак, еще раз, мой вопрос ... как я могу запустить что-то после того, как обновление фактически закончено? (То есть, не полагаясь на какую-то нелепую произвольную задержку, вызваннуюsetTimeout.)

Альтернативный вопрос: я делаю что-то не так или это ошибка в Chrome?

Побочный вопрос: если у кого есть IE 10, мне интересно, как он себя ведет в этой ситуации ..

Ответы на вопрос(2)

Ваш ответ на вопрос