Tx在以下情况下提交:
这意味着如果没有提交请求,则在返回事件循环之前不会提交。这些事实构成了两个有问题的状态:
如果多个“readwrite”事务试图访问它们 对象存储(即,如果它们具有重叠的范围),该事务 首先创建的必须是可以访问的事务 对象存储首先。由于以前的要求 段落,这也意味着它是唯一拥有的交易 在事务完成之前访问对象库。
通过带有反压的递归请求提交从成功回调中将新任务排入事件循环队列的示例:
function recursiveFn(key) {
val req = store.get(key)
req.onsuccess = function() {
observer.onNext(req.result).onsuccess { recursiveFn(nextKey) }
}
}
Observer#onNext // returns Future[Ack] Ack is either Continue or Cancel
现在可以onsuccess
或onNext
执行setTimeout(0)或不使整个事情成为一个事务的一部分吗?
奖金问题:
我认为ReadOnly事务是暴露给消费者/用户的,因为如果你从前一个成功回调中递归提交新请求,那么很难检测到批量读取的结束吗?否则我没有看到任何其他原因让他们接触到用户,对吗?
答案 0 :(得分:2)
我不确定我是否完全理解您的问题,但我会就是否可以安全地使用IDB事务事件来移动状态机提供答案。
是和否。在理论上是的,在实践中没有。
事务的生命周期持续时间与引用一样长:只要它被引用,它就是“活动的”,之后它被称为“已完成”并且事务已被提交。
理论上,只要事务成功提交,oncomplete
就会触发。 spec中有一个有用的提示,表明你可以循环:
要确定事务是否已成功完成,请侦听事务的complete事件而不是IDBObjectStore.add请求的成功事件,因为事件在成功事件触发后仍可能失败。
要安全使用此机制,请务必关注包含onblocked
和onabort
在内的非成功事件。
实际上,我发现交易在长期存在或连续分批完成时会变得非常复杂(正如您在另一个IDB评论中所指出的那样)。我通常不会将我的应用程序设计为需要棘手的行为,因为无论规范如何说它应该是行为,我都会在Firefox和Chromium中看到不稳定的交易(但主要是Blink,有趣的是),尤其是当多个标签打开时。 / p>
我花了很多时间重写dash来重用事务以获得所谓的性能提升。最后它甚至无法通过我的基本写测试,我被迫放弃同步/排队/连续交易并再次重写。这次我选择了一次一次交易的模型,这个模型速度较慢,但对我来说,更可靠(建议避免使用我的lib并使用ydn进行批量插入)。
我不确定您的应用程序要求,但我认为将您的I / O绑定到事件循环中似乎是一个灾难性的想法。如果我需要一个事件循环,就像我理解的那样,我肯定会使用requestAnimationFrame()
来限制回调,如果我需要更少的刻度而不是每33毫秒一个。