indexedDB.open() 没有传递成功事件
indexedDB.open() does not deliver the success event
人们通常这样做:
var DBOpenRequest = window.indexedDB.open("toDoList");
DBOpenRequest.onsuccess = function(event) {//Good};
第二行代码如果没有及时执行,onsuccess会错过事件
嗯,这个问题并不经常发生,因为这两条线之间的延迟通常很短。但是,这两条线的结果仍然不是确定性的。在我的机器上,如果我在这两条线之间模拟 270 毫秒的延迟,事件将会被错过。我认为 open() 的当前签名不合适。
正确的异步设计模式是先设置事件处理器,然后才开始真正的异步操作。 open() 函数应将回调作为参数。
有意见吗?
更新的问题:
async function test(delay)
{
var req = indexedDB.open("test");
//Simulate a delay
await new Promise(resolve => setTimeout(resolve, delay));
req.onsuccess = function (evt) {console.log("Good");};
}
test(1);
如果延迟为 1 毫秒,将记录 "Good"。如果延迟为 1000 毫秒,如 test(1000),则不会记录 "Good",这意味着不会调用事件处理程序。
- 复习 EventListener 设计模式的基础知识。 indexedDB 基本上采用了在多个 Javascript 组件(例如 DOM 元素和 XMLHttpRequest)中使用的相同模式,并假设您熟悉该模式。
- 查看 JavaScript 的事件循环是如何运行的,因为理解异步代码很重要。
在分派事件之前或之后绑定侦听器函数与异步代码的上下文无关。基本上,您声明的绑定发生 later,因为它是在以下代码行的语句中编写的,实际上并没有发生 later。无论该行写在何处(除非有一些迂腐的例外),它都发生在与上一行相同的事件循环周期内,调用打开。该事件最早直到 next 事件循环时期才会触发,这将始终发生在前一个事件循环时期发生绑定之后。总是。卦运行开.
执行导致事件的代码的调用与该事件的最终发生和接收之间的时间延迟是无关紧要的。这种延迟与许多其他事情有关,比如你的机器有多强大,你的电脑有多少资源可用,你的脚本试图做其他事情有多忙,甚至可能你加载了多少垃圾到 dom,因为这些事情中的任何一个都可能有助于延长事件循环当前时期的生命周期。延迟被实施为无限期的等待期。它基本上被编码为"occur in some later event loop epoch"。这可能是 1 纳秒之后,也可能是 10000 秒之后,延迟量是无关紧要的。唯一相关的问题是事件在 next 事件循环时期触发,这是某个时间 after 所有其他事件都发生在先前的事件循环时期.
第二行总是会以及时的方式执行,因为这里及时的基本标准就是"in the same epoch of the event loop",这里,及时,又可以表示任何时间。
结果是确定性的。不要再将时间滴答视为流逝的毫秒数或类似的东西。而是将时间视为事件循环的滴答声。每个刻度可以花费可变的时间。壁虱是有序的。蜱虫是连续的。 Tick 2 将在 Tick 1 之后发生。Tick 3 将在 Tick 2 之后发生等等。因此,这在执行顺序方面是确定性的,每个 tick 的时间量可变。一个 tick 只是一个 period 的时间,尽管这些周期可能有可变的数量,但您仍然可以声明某些周期发生在其他周期之前或之后的事实。此外,从来没有两个时期重叠(不是真正的并发,实际上不是多线程,也不是严格交错)。
我不知道,想象一下秒表、旧手表或墙上的时钟。指针绕着手表的表面移动。假设手从起点走完需要 1 秒,一直绕 360 度,return 到起点。每次往返,我们称之为纪元或滴答。然后我们可以通过计算返回起点的次数来计算发生了多少次往返。基本上是epochs的数量,基本上是有基数的。
现在想象一下两块手表。第一只手表仍然需要整整一秒才能走完一圈。然而,第二只表,让我们假装,它是一块旧的慢表,走一圈需要 2 秒。频率减半。现在,问题是,即使两只手表的计时不同,我们仍然 可以做出像"watch 1 did 10 roundtrips" 和"watch 2 did 5 roundtrips".
这样的声明
现在,更进一步。让我们看一看,引入运行dom个外部因素。当指针围绕表盘旋转时,宇宙射线会对指针的速度产生零星的引力效应。因此,一些往返行程几乎没有遇到减速带,并且需要更长的时间。所以我们得到了往返时间的分布。我们仍然有平均往返时间,但不是 常量 往返时间。在往返 1 中,我们的手表可能会在 1 秒内完成行程。在第 2 轮中,可能需要 2.5 秒。在第 3 轮中,可能需要 1 纳秒。时间是可变的。但是,这种可变性并不能阻止我们陈述诸如 "well there were 3 round trips when we observed it"、"well the second round trip occurred after the first one" 和 "no roundtrip travel ever occurred at the same time as another (round trip 1 and 2 and 3 have no overlap)".
之类的东西
这些往返是 javascript 事件循环的纪元。您的绑定全部发生在往返#1 中。由于打开 indexedDB never 而发生的事件发生在往返 #1 中,无论您在哪里编写它,以任何顺序编写,等等。该事件总是在任一往返中发生#2,或#3,或基本上任何时期在 往返#1 之后。即使事件在#1 中在技术上是神奇的 'ready',它仍然要到 #2 或更晚的时候才会公开。
因为open的调用和open监听器的绑定都发生在第一个epoch,所以说监听器是在调用open之前绑定还是之后绑定是无关紧要的。因为这些都发生在 #1,而 open 事件最早要到 #2 才会发生。
人们通常这样做:
var DBOpenRequest = window.indexedDB.open("toDoList");
DBOpenRequest.onsuccess = function(event) {//Good};
第二行代码如果没有及时执行,onsuccess会错过事件
嗯,这个问题并不经常发生,因为这两条线之间的延迟通常很短。但是,这两条线的结果仍然不是确定性的。在我的机器上,如果我在这两条线之间模拟 270 毫秒的延迟,事件将会被错过。我认为 open() 的当前签名不合适。
正确的异步设计模式是先设置事件处理器,然后才开始真正的异步操作。 open() 函数应将回调作为参数。
有意见吗?
更新的问题:
async function test(delay)
{
var req = indexedDB.open("test");
//Simulate a delay
await new Promise(resolve => setTimeout(resolve, delay));
req.onsuccess = function (evt) {console.log("Good");};
}
test(1);
如果延迟为 1 毫秒,将记录 "Good"。如果延迟为 1000 毫秒,如 test(1000),则不会记录 "Good",这意味着不会调用事件处理程序。
- 复习 EventListener 设计模式的基础知识。 indexedDB 基本上采用了在多个 Javascript 组件(例如 DOM 元素和 XMLHttpRequest)中使用的相同模式,并假设您熟悉该模式。
- 查看 JavaScript 的事件循环是如何运行的,因为理解异步代码很重要。
在分派事件之前或之后绑定侦听器函数与异步代码的上下文无关。基本上,您声明的绑定发生 later,因为它是在以下代码行的语句中编写的,实际上并没有发生 later。无论该行写在何处(除非有一些迂腐的例外),它都发生在与上一行相同的事件循环周期内,调用打开。该事件最早直到 next 事件循环时期才会触发,这将始终发生在前一个事件循环时期发生绑定之后。总是。卦运行开.
执行导致事件的代码的调用与该事件的最终发生和接收之间的时间延迟是无关紧要的。这种延迟与许多其他事情有关,比如你的机器有多强大,你的电脑有多少资源可用,你的脚本试图做其他事情有多忙,甚至可能你加载了多少垃圾到 dom,因为这些事情中的任何一个都可能有助于延长事件循环当前时期的生命周期。延迟被实施为无限期的等待期。它基本上被编码为"occur in some later event loop epoch"。这可能是 1 纳秒之后,也可能是 10000 秒之后,延迟量是无关紧要的。唯一相关的问题是事件在 next 事件循环时期触发,这是某个时间 after 所有其他事件都发生在先前的事件循环时期.
第二行总是会以及时的方式执行,因为这里及时的基本标准就是"in the same epoch of the event loop",这里,及时,又可以表示任何时间。
结果是确定性的。不要再将时间滴答视为流逝的毫秒数或类似的东西。而是将时间视为事件循环的滴答声。每个刻度可以花费可变的时间。壁虱是有序的。蜱虫是连续的。 Tick 2 将在 Tick 1 之后发生。Tick 3 将在 Tick 2 之后发生等等。因此,这在执行顺序方面是确定性的,每个 tick 的时间量可变。一个 tick 只是一个 period 的时间,尽管这些周期可能有可变的数量,但您仍然可以声明某些周期发生在其他周期之前或之后的事实。此外,从来没有两个时期重叠(不是真正的并发,实际上不是多线程,也不是严格交错)。
我不知道,想象一下秒表、旧手表或墙上的时钟。指针绕着手表的表面移动。假设手从起点走完需要 1 秒,一直绕 360 度,return 到起点。每次往返,我们称之为纪元或滴答。然后我们可以通过计算返回起点的次数来计算发生了多少次往返。基本上是epochs的数量,基本上是有基数的。
现在想象一下两块手表。第一只手表仍然需要整整一秒才能走完一圈。然而,第二只表,让我们假装,它是一块旧的慢表,走一圈需要 2 秒。频率减半。现在,问题是,即使两只手表的计时不同,我们仍然 可以做出像"watch 1 did 10 roundtrips" 和"watch 2 did 5 roundtrips".
这样的声明现在,更进一步。让我们看一看,引入运行dom个外部因素。当指针围绕表盘旋转时,宇宙射线会对指针的速度产生零星的引力效应。因此,一些往返行程几乎没有遇到减速带,并且需要更长的时间。所以我们得到了往返时间的分布。我们仍然有平均往返时间,但不是 常量 往返时间。在往返 1 中,我们的手表可能会在 1 秒内完成行程。在第 2 轮中,可能需要 2.5 秒。在第 3 轮中,可能需要 1 纳秒。时间是可变的。但是,这种可变性并不能阻止我们陈述诸如 "well there were 3 round trips when we observed it"、"well the second round trip occurred after the first one" 和 "no roundtrip travel ever occurred at the same time as another (round trip 1 and 2 and 3 have no overlap)".
之类的东西这些往返是 javascript 事件循环的纪元。您的绑定全部发生在往返#1 中。由于打开 indexedDB never 而发生的事件发生在往返 #1 中,无论您在哪里编写它,以任何顺序编写,等等。该事件总是在任一往返中发生#2,或#3,或基本上任何时期在 往返#1 之后。即使事件在#1 中在技术上是神奇的 'ready',它仍然要到 #2 或更晚的时候才会公开。
因为open的调用和open监听器的绑定都发生在第一个epoch,所以说监听器是在调用open之前绑定还是之后绑定是无关紧要的。因为这些都发生在 #1,而 open 事件最早要到 #2 才会发生。