これはかなり平凡なことだと思います。IndexedDBデータベースのオブジェクトを更新してから、更新された値を使用するコードを実行したいと思います。
私が最初にしたことはcursor.update
、Firefoxで動作するを呼び出した後にコールバック関数を実行することでした。ただし、Chromeでは失敗します。次のコードが実行される前に更新は行われません。(私が理解しているように)更新は非同期であるため、これは競合状態である可能性があります。
そこで、のonsuccess
シグナルを使用しcursor.update
てコールバック関数を呼び出す必要があると思いました。しかし、驚いたことに、それはChromeでも機能しないようです。
jsFiddleで実行できるいくつかのサンプルコード...面白いことに、これは何らかの理由でjsFiddleのFirefoxでクラッシュするようですが、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(現在の安定バージョン)では、ログに記録された3つのオブジェクトはすべて同一であり、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}
最初の2つの出力の1つが43に更新されることがありますが、通常は42です。
繰り返しになりますが、私の質問は...更新が実際に終了した後に何かを実行するにはどうすればよいですか?(つまり、で引き起こされるばかげた任意の遅延に依存することなくsetTimeout
。)
別の質問:私は何か間違ったことをしていますか、それともこれはChromeのバグですか?
副次的な質問:IE 10を持っている人がいたら、この状況でどのように動作するのだろうか。