【问题标题】:Dexie modify() fails without throwing an errorDexie modify() 失败而不抛出错误
【发布时间】:2018-12-31 07:30:37
【问题描述】:

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 次?我完全被难住了。

【问题讨论】:

  • 您是否尝试过捕获所有错误而不仅仅是Dexie.ModifyError?这可以为您指明正确的方向。 .catch(function(e){ console.error(e); throw e; }); 编辑:啊,没关系,我没有仔细阅读以看到页面确实重新加载。
  • 是的,无论如何添加 ModifyError 是在常规错误捕获从未记录任何内容之后的最新更改。

标签: javascript html indexeddb dexie


【解决方案1】:

直到我用 一千 条记录填充数据库后,我才设法重现这一点。之后,页面开始过早地重新加载,在项目存储之前。

我在 JSFiddle 上遇到的错误与您描述的不完全一样,该页面在尝试重新加载后只是显示 404,但我认为我知道发生了什么。 p>

由于window.location.reload(),页面未重新加载。相反,表单的提交事件会冒泡到其默认行为,因为它没有在任何地方明确阻止。所以有一个竞争条件;当只有一个小数据集时,Dexie 设法在表单重新加载页面之前完成它的工作。当数据集增长时,更改需要更长的时间,表单的提交事件会赢得比赛。

要解决此问题,请从 onsubmit 回调中返回 false 以防止默认提交行为。

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.

【讨论】:

  • 做到了!回想起来,竞争条件似乎很明显,但我从来没有想过以这种方式解决它。谢谢谢谢!
  • 公平地说,花几个小时在回想起来似乎很明显的错误上就像编程的 83%。很高兴我能帮忙:)
猜你喜欢
  • 1970-01-01
  • 2012-07-24
  • 2020-03-17
  • 2013-08-18
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
相关资源
最近更新 更多