Dexie modify() 失败但没有抛出错误
Dexie modify() fails without throwing an error
TL;DR: collection.modify() 适用于少数记录,但在尝试一次修改超过 10 条记录时失败。为什么?
我有一些代码使用 Javascript、HTML 和 IndexedDB 上的 Dexie 包装器显示数据库并与之交互。问题是:我一次只能修改几条记录。如果我尝试超过 ~8-10 条记录,modify() 会失败且没有错误。
下面是我调用数据库和绘制查询表的方式:
//Every time the page refreshes, the db is open and draws tables
$document.ready(function(){
//Open database
db=new Dexie("peopleManager");
db.version(1).stores({
people: "id++, name, location"
});
//Call functions that draw query tables
showDallas();
showNewYork();
});
//Draws an HTML table of people who work in Dallas
function showDallas(){
var output = '';
db.people
.where("location")
.equals("Dallas")
.each
(function(people){
output += "<tr align='center'>";
output += "<td>"+people.id+"</td>";
output += "<td>"+people.name+"</td>";
output += "</tr>";
$('#dallas').html(output);
});
}
//Draws an HTML table of people who work in NY
function showNewYork(){
var output = '';
db.people
.where("location")
.equals("New York")
.each
(function(people){
output += "<tr align='center'>";
output += "<td>"+people.id+"</td>";
output += "<td>"+people.name+"</td>";
output += "</tr>";
$('#newYork').html(output);
});
}
这是一直失败的函数。单击 HTML 按钮会触发它:
//Move all to New York
function moveToNewYork(){
db.transaction('rw', db.people, function(){
db.people.where("location").equals("Dallas").modify({location: "New York"});
}).then(function(){
window.location.reload();
}).catch(Dexie.ModifyError, function(e){
console.error(e.failures.length + "failed to hire modify");
throw e;
});
}
HTML 按钮:
<form role = "form" onSubmit = "moveToNewYork()">
<button type="submit" class="btn btn-primary">Move All</button></form>
我可以修改不到 10 条记录。超过十个,页面刷新,数据库没有变化,也没有错误记录。遵循 the documentation 但没有看到任何 modify() 需要更改 10 条以上记录的示例。我还没有发现任何显示 modify() 事务在一定数量的记录后失败的信息。
有人看到我做错了什么,或者我该如何进一步解决这个问题?
请注意,实际代码很长,还有大约 20 个其他只读操作在进行。
更新:这里是 full JSFiddle 显示错误。有了这些(非常小的)记录,我可以在 modify() 开始失败之前达到 12-15。奇怪的是,再次随机点击几次 modify() 可能会工作 8 次中的 1 次?我完全被难住了。
直到我用 千 条记录填充数据库后,我才设法重现。在那之后,页面开始过早地重新加载,在项目被存储之前。
我在 JSFiddle 上遇到的错误与您描述的不完全相同,在尝试重新加载后,该页面只是用 404 提示我,但我 认为 我知道是什么进行中。
由于 window.location.reload()
,页面没有重新加载。相反,表单的提交事件冒泡到它的默认行为,因为它没有在任何地方被明确阻止。所以有一个竞争条件;当只有一个小数据集时,Dexie 设法在表单重新加载页面之前完成其工作。当数据集增长时,更改需要更长的时间,表单的提交事件将赢得比赛。
要解决此问题,return false
来自 onsubmit 回调以防止默认提交行为。
HTML:
<form role="form" onSubmit="return moveToNewYork()">
^^^^^^ add "return" here
JS:
function moveToNewYork() {
db.transaction('rw', db.people, function() {
db.people.where("location").equals("Dallas").modify({
location: "New York"
});
}).then(function() {
window.location.reload();
}).catch(Dexie.ModifyError, function(e) {
console.error(e.failures.length + "failed to hire modify");
throw e;
});
return false; // add "return false" here
}
并对其他修改形式和功能也进行相同的修改。
相关:SO - How to prevent form from being submitted.
TL;DR: collection.modify() 适用于少数记录,但在尝试一次修改超过 10 条记录时失败。为什么?
我有一些代码使用 Javascript、HTML 和 IndexedDB 上的 Dexie 包装器显示数据库并与之交互。问题是:我一次只能修改几条记录。如果我尝试超过 ~8-10 条记录,modify() 会失败且没有错误。
下面是我调用数据库和绘制查询表的方式:
//Every time the page refreshes, the db is open and draws tables
$document.ready(function(){
//Open database
db=new Dexie("peopleManager");
db.version(1).stores({
people: "id++, name, location"
});
//Call functions that draw query tables
showDallas();
showNewYork();
});
//Draws an HTML table of people who work in Dallas
function showDallas(){
var output = '';
db.people
.where("location")
.equals("Dallas")
.each
(function(people){
output += "<tr align='center'>";
output += "<td>"+people.id+"</td>";
output += "<td>"+people.name+"</td>";
output += "</tr>";
$('#dallas').html(output);
});
}
//Draws an HTML table of people who work in NY
function showNewYork(){
var output = '';
db.people
.where("location")
.equals("New York")
.each
(function(people){
output += "<tr align='center'>";
output += "<td>"+people.id+"</td>";
output += "<td>"+people.name+"</td>";
output += "</tr>";
$('#newYork').html(output);
});
}
这是一直失败的函数。单击 HTML 按钮会触发它:
//Move all to New York
function moveToNewYork(){
db.transaction('rw', db.people, function(){
db.people.where("location").equals("Dallas").modify({location: "New York"});
}).then(function(){
window.location.reload();
}).catch(Dexie.ModifyError, function(e){
console.error(e.failures.length + "failed to hire modify");
throw e;
});
}
HTML 按钮:
<form role = "form" onSubmit = "moveToNewYork()">
<button type="submit" class="btn btn-primary">Move All</button></form>
我可以修改不到 10 条记录。超过十个,页面刷新,数据库没有变化,也没有错误记录。遵循 the documentation 但没有看到任何 modify() 需要更改 10 条以上记录的示例。我还没有发现任何显示 modify() 事务在一定数量的记录后失败的信息。
有人看到我做错了什么,或者我该如何进一步解决这个问题?
请注意,实际代码很长,还有大约 20 个其他只读操作在进行。
更新:这里是 full JSFiddle 显示错误。有了这些(非常小的)记录,我可以在 modify() 开始失败之前达到 12-15。奇怪的是,再次随机点击几次 modify() 可能会工作 8 次中的 1 次?我完全被难住了。
直到我用 千 条记录填充数据库后,我才设法重现。在那之后,页面开始过早地重新加载,在项目被存储之前。
我在 JSFiddle 上遇到的错误与您描述的不完全相同,在尝试重新加载后,该页面只是用 404 提示我,但我 认为 我知道是什么进行中。
由于 window.location.reload()
,页面没有重新加载。相反,表单的提交事件冒泡到它的默认行为,因为它没有在任何地方被明确阻止。所以有一个竞争条件;当只有一个小数据集时,Dexie 设法在表单重新加载页面之前完成其工作。当数据集增长时,更改需要更长的时间,表单的提交事件将赢得比赛。
要解决此问题,return false
来自 onsubmit 回调以防止默认提交行为。
HTML:
<form role="form" onSubmit="return moveToNewYork()">
^^^^^^ add "return" here
JS:
function moveToNewYork() {
db.transaction('rw', db.people, function() {
db.people.where("location").equals("Dallas").modify({
location: "New York"
});
}).then(function() {
window.location.reload();
}).catch(Dexie.ModifyError, function(e) {
console.error(e.failures.length + "failed to hire modify");
throw e;
});
return false; // add "return false" here
}
并对其他修改形式和功能也进行相同的修改。
相关:SO - How to prevent form from being submitted.