indexedDB.open()不提供成功事件

时间:2018-04-21 22:47:30

标签: javascript asynchronous async-await indexeddb

人们通常这样做:

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 ms,将记录“Good”。如果延迟是1000 ms,如test(1000),则不会记录“Good”,这意味着不会调用事件处理程序。

1 个答案:

答案 0 :(得分:1)

  1. 查看EventListener设计模式的基础知识。 indexedDB基本上采用了与DOM元素和XMLHttpRequest等几个Javascript组件相同的模式,并假设您熟悉模式。
  2. 了解JavaScript的事件循环如何运作,因为理解异步代码非常重要。
  3. 在调度事件之前或之后绑定侦听器函数在异步代码的上下文中是无关紧要的。基本上,您声明的绑定发生在以后,因为它是在以下代码行的语句中编写的,实际上并不会发生以后。无论线写在哪里(除了一些迂腐的例外),它都发生在事件循环的同一刻度内,与前一行,即打开的调用相同。直到最早的 next 事件循环时期才会触发事件,该时间始终是在前一个事件循环时期发生绑定之后。总是。保证。

    调用导致事件的代码与最终发生和接收事件之间的时间延迟是无关紧要的。这种延迟与许多其他因素有关,例如你的机器有多强大,你的电脑可以使用多少资源,你的脚本尝试做其他事情有多忙,甚至可能是你装入dom的垃圾有多少,因为任何这些事情可能有助于延长事件循环当前时期的生命周期。延迟实现为无限期等待。它基本上被编码为"出现在一些后来的事件循环时代"中。这可能是1纳秒后,可能是10000秒后,延迟量是无关紧要的。唯一相关的问题是事件在 next 事件循环时期中触发,这是之后之后在先前事件循环时期中发生的所有其他事件。

    第二行将始终以及时方式执行,因为此处及时的基本标准只是"在事件循环的同一时期",在这里,及时,再次,可能意味着任何时间。

    结果是确定性的。不要再考虑时间滴答作为经过的毫秒数或类似的事情。相反,将时间视为事件循环的滴答。每个滴答可能需要不同的时间。蜱虫是有序的。蜱是连续的。 Tick 1将在Tick 1之后发生.Tick 3将在Tick 2之后发生。等等。因此,这对于执行顺序是确定性的,考虑每个tick的可变时间量。刻度只是时间的期间,尽管期间可能具有可变金额,但您仍然可以声明某些期间在某个其他期间之前或之后发生的事实。此外,没有两个时期重叠(不是真正的并发,实际上不是多线程,不是严格交错)。

    我不知道,想象一下秒表,旧手表或墙上的钟表。手在手表的表面周围移动。让我们假设手从起点开始行进需要1秒钟,一直到360度左右,然后返回起点。每次往返,我们称之为一个纪元,或一个刻度线。然后我们可以通过计算起点上的回合次数来计算发生了多少次往返。基本上有时代的数量,基本上有基数。

    现在想象两款手表。第一只手表仍然需要一秒钟的时间才能完成旅行。然而,第二块手表让我们假装,这是一款老旧的慢速手表,需要2秒钟才能完成旅行。频率的一半。现在,问题是,即使两款手表的时间不同,我们仍然可以做出类似于"手表1进行了10次往返的声明"并且"观看2进行了5次往返"。

    现在,进一步说明。让我们来看一下,并引入随机的外部因素。宇宙射线在手表周围旋转时会对手的速度产生零星的重力影响。因此,一些往返几乎没有速度颠簸,需要更长的时间。所以我们得到了往返次数的分布。我们仍有平均往返时间,但不是常数往返时间。在往返1中,我们的手表可以在1秒内完成旅行。在第2轮,可能需要2.5秒。在第3轮中,可能需要1纳秒。时间是变化的。但是,这种可变性并不能阻止我们说出像#34;当我们观察它时会有3次往返,并且"以及第二次往返发生在第一次"之后,并且"没有任何往返旅行同时发生(往返1和2和3没有重叠)"

    这些往返是javascript事件循环的时代。您的绑定都发生在往返#1中。由于打开indexedDB 从不而发生的事件发生在往返#1中,无论您在何处编写它,无论您编写它的顺序等等。事件始终发生在往返#2中, 往返#1后的#3,或基本上任何纪元。即使这个活动在技术上是神奇的,也已经准备好了。在#1中,它直到#2或更晚才会曝光。

    因为对open的调用和open侦听器的绑定都发生在第一个时代,所以在调用open之前或之后讨论监听器是否绑定是无关紧要的。因为这些都发生在#1中,并且公开事件直到最早的#2才会发生。