多个onClick选择器如何按时工作?

时间:2018-08-29 08:59:17

标签: javascript asynchronous onclick

当前,附加onClick事件的代码如下:

$("#LieblingsButton").click(function(){
    reactivateFavSeatCheck()
  })

  $("#LieblingsButton").click(function(){
    checkForWeekReservationByFavSeatButton()
  })

  $("#LieblingsButton").click(function(){
    fetchDataFromDatabase()
  })

  $("#LieblingsButton").click(function(){
    executeReservation()
  })

fetchDataFromDatabase()做一些异步工作,但是异步/等待和诺言已经解决了这一问题。 executeReservation()仅在fetchDataFromDatabase()完成执行后才能开始。

当前,一切正常。但是我担心可能只是这样,因为事态允许。如果fetchDataFromDatabase()花了几毫秒“太长”怎么办?

我已经了解到,当您通过jquery向一个元素添加多个事件处理程序时(使用本机JS怎么样?),它们将按照您在代码中确定的顺序触发。但是我不知道该“规则”是否还包含Event2仅在Event1已经完成执行时才会触发吗?

此外,以下代码是否与上面的代码相同(从功能角度而言)?

$("#LieblingsButton").click(function(){
    reactivateFavSeatCheck()
    checkForWeekReservationByFavSeatButton()
    fetchDataFromDatabase()
    executeReservation()
  })

1 个答案:

答案 0 :(得分:1)

第一件事是:JS执行本质上是单线程的。无论您的代码看起来多么异步,在任何给定时间都只有一部分运行。您可以在此处详细了解以下内容:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

其次,事件监听器按照连接的时间顺序循环触发。您可以这样想:

handlers.forEach((handler) => {
  try { handler(event); } catch (e) { /* put warning in console */ }
});
  

但是我担心情况可能只会如此,因为过激的情况允许这样做。如果fetchDataFromDatabase()花费几毫秒“太长”怎么办?

通过以下测试,您可以观察到第一个事件侦听器中的while循环如何阻止第二个事件监听器触发,从而证实您的怀疑。 注意:我没有将其作为代码段嵌入,因为覆盖控制台的代码段以某种方式破坏了此示例。只需将其粘贴到浏览器控制台中即可。

// $(e).click(fn) roughly equals e.addEventListener('click', fn);

window.addEventListener('test', () => {
  console.log('first handler', new Date());
  const time = Date.now();
  while (Date.now() - time < 2000) {}
});

window.addEventListener('test', () => {
  console.log('second handler', new Date());
});

window.dispatchEvent(new Event('test'));

但是...

如果您异步进行工作,情况会好得多。

window.addEventListener('test', () => {
  setTimeout(() => {
    console.log('first handler');
  }, 1000);
});

window.addEventListener('test', () => {
  console.log('second handler');
});

window.dispatchEvent(new Event('test'));

在此示例中,您可以看到尽管第一个事件处理程序安排了计时器,但这不会阻止下一个事件侦听器运行。如果您要说XHR请求,也是如此。

所以最后,有了这些信息,我们可以说,最好使用单个事件侦听器,就像在第二个片段中一样。