运行code的对象在IndexedDB的(特别是在Chrome)更新后,才 [英] Running code only after an object is updated in IndexedDB (particularly in Chrome)

查看:145
本文介绍了运行code的对象在IndexedDB的(特别是在Chrome)更新后,才的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得这是做pretty平凡的事情。我想在IndexedDB的数据库更新一个对象,然后运行一些code之后,使用更新后的值。

I feel like this is a pretty mundane thing to do. I want to update an object in an IndexedDB database and then run some code after which uses the updated values.

我本来只是运行我的回调函数调用 cursor.update ,它在Firefox的作​​品之后。但在Chrome中出现故障时,更新并不以下code运行前发生。这可能是一个竞争条件,因为(据我所知)的更新是异步的。

What I originally did was just run my callback function after calling cursor.update, which works in Firefox. But it fails in Chrome, the update doesn't happen before the following code is run. This is likely a race condition, since (as I understand it) updates are asynchronous.

于是我想我应该用 cursor.update 的onSuccess 信号打电话给我的回调函数。但出乎我的意料,这也似乎并没有在Chrome!工作

So then I thought I should use the onsuccess signal of cursor.update to call my callback function. But much to my surprise, that also doesn't seem to work in Chrome!

一些示例code这你可以在运行的jsfiddle ...虽然可笑,这似乎在Firefox崩溃在的jsfiddle出于某种原因,但Chrome的正常工作;为Firefox可以在本地运行它和它的作品(这将产生输出JavaScript控制台在您的浏览器):

Some example code which you can run on jsFiddle... although amusingly this seems to crash in Firefox in jsFiddle for some reason, but Chrome works fine; for Firefox you can run it locally and it works (this produces output on the JavaScript console in your browser):

<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):

Observed behavior (all on Ubuntu 12.10, FWIW):

在Firefox 19(当前的稳定版本),所有三个记录的对象是相同的,设置为43:

In Firefox 19 (current stable version), all three logged objects are identical, with value set to 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(当前不稳定的版本),我通常会得到这样的输出:

In Chrome 25 (current stable version) and 27 (current unstable version), I usually get this output:

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

Sometimes one of the first two outputs is updated to 43, but it's usually a 42.

如此反复,我的问题是如何......我可以运行更新后的东西实际上是完成了吗? (也就是说,不依赖于与的setTimeout 感应有些可笑任意延迟。)

So again, my question is... how can I run something after the update is actually finished? (That is, without relying on some ridiculous arbitrary delay induced with setTimeout.)

替代的问题:我是不是做错了什么,或者这是浏览器的错误

Alternative question: Am I doing something wrong, or is this a bug in Chrome?

侧的问题:如果任何人有IE 10,我不知道它的行为在这种情况下..

Side question: If anyone has IE 10, I wonder how it behaves in this situation..

推荐答案

您不需要setTimeout的,只是等待交易完成如下:

You don't need setTimeout, just wait transaction to complete as follow:

// Update data
var tx = db.transaction("objects", "readwrite");

tx.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);
        };
    };

};

tx.oncomplete = function() {     
    // 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);
   };
 }

这是IndexedDB的API的混乱方面之一。请求的onSuccess不要吝啬你的成功是写入到数据库中。只有交易的onComplete确认。原因是,你仍然可以中止交易 tx.abort()后写请求。

This is one of the confusing aspect of IndexedDB API. Request onsuccess don't not mean your success is written to the database. Only transaction oncomplete confirm it. The reason is, you can still abort transaction tx.abort() after write request.

这篇关于运行code的对象在IndexedDB的(特别是在Chrome)更新后,才的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆