dum*_*ter 3 javascript asynchronous google-chrome cross-browser indexeddb
我觉得这是一件非常平凡的事情.我想更新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>
Run Code Online (Sandbox Code Playgroud)
观察到的行为(全部在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}
Run Code Online (Sandbox Code Playgroud)
在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}
Run Code Online (Sandbox Code Playgroud)
有时前两个输出中的一个更新为43,但通常为42.
所以,我的问题是......在更新实际完成后如何运行?(也就是说,不依赖于引起的一些荒谬的任意延迟setTimeout
.)
替代问题:我做错了什么,或者这是Chrome中的错误?
附带问题:如果有人有IE 10,我想知道它在这种情况下的表现如何..
您不需要setTimeout,只需等待事务完成如下:
// 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);
};
}
Run Code Online (Sandbox Code Playgroud)
这是IndexedDB API令人困惑的一个方面.请求成功并不意味着您的成功被写入数据库.只有完成交易才能确认.原因是,您仍然可以tx.abort()
在写入请求后中止事务.
归档时间: |
|
查看次数: |
2580 次 |
最近记录: |