Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript/浏览器:事件分派确切发生在何时?_Javascript_Events_Asynchronous_Concurrency_Event Loop - Fatal编程技术网

javascript/浏览器:事件分派确切发生在何时?

javascript/浏览器:事件分派确切发生在何时?,javascript,events,asynchronous,concurrency,event-loop,Javascript,Events,Asynchronous,Concurrency,Event Loop,这表示在浏览器中同步调度手动事件。然而,我的问题是与用户相关的事件(真正的点击),而不是手动触发的事件 我使用button+onclick处理程序创建了一个,该处理程序执行一些同步工作2秒钟(阻止同步等待,足够长的时间让我的眼睛看到发生了什么)。打开控制台以查看console.logs 测试。我在按钮上按了几下。尽管第一次单击(及其同步处理)会使按钮被按下(看起来是禁用的),其他单击也会被存储,并在以后通过事件循环异步处理 问题是: 事件分派确切发生在什么时候?用户事件(如单击)是否立即推送到

这表示在浏览器中同步调度手动事件。然而,我的问题是与用户相关的事件(真正的点击),而不是手动触发的事件

我使用button+onclick处理程序创建了一个,该处理程序执行一些同步工作2秒钟(阻止同步等待,足够长的时间让我的眼睛看到发生了什么)。打开控制台以查看
console.log
s

测试。我在按钮上按了几下。尽管第一次单击(及其同步处理)会使按钮被按下(看起来是禁用的),其他单击也会被存储,并在以后通过事件循环异步处理

问题是:

  • 事件分派确切发生在什么时候?用户事件(如单击)是否立即推送到JS消息队列,或者是否存在中间Web API队列。。。或者换句话说,此事件调度与哪个队列相关
  • 在用户事件(不是手动事件)的情况下,大多数事件(
    单击
    模糊
    ,等等-除了
    加载
    )是同步处理的,这意味着什么?考虑到上面的测试,第一次单击将执行同步阻塞回调(我希望在此期间不会发生其他事情),并且,无论如何,下一次单击将存储在队列中。所以无论如何,存储事件都是并行的(必须是并行的,因为主javascirpt线程很忙)。理论上,it事件是异步处理的,这有什么区别吗


显示了对于给定的click事件,事件冒泡并调用所有相关的事件处理程序,就像事件冒泡被阻塞一样,直到发生任何其他事件(本例中为超时)。但是仍然不清楚为什么事件调度是同步的。

在实际事件的上下文中谈论同步是没有意义的,因为只有当当前执行堆栈被清空时,即当没有更多的同步代码可执行时,才会处理事件队列。这使得相关的事件处理程序异步。对于在fiddle中提供的click事件处理程序也是如此

正在运行的代码在运行时会阻止任何其他操作,这并不表示该代码是如何被触发的:异步还是同步。在这两种情况下,持续2秒的忙循环将阻塞2秒。当我们说代码异步运行时,它只说明代码是如何/何时被调用的,而不是它是如何运行的。同步和异步代码都以阻塞的方式运行。这有一些例外——例如,在它们自己的线程中运行

这些“真实”事件被推送到JS消息队列上。当然,它们首先是从操作系统事件队列中消耗的,但这是特定于实现的。重要的是,它们最终与一个处理程序一起出现在JS消息队列中。JavaScript引擎仅在以前运行的代码运行时处理事件。因此,这些事件处理程序被异步调用

对于“手动”事件,即由jQuery的
.trigger()
方法等代码触发的事件,区分异步和同步是有意义的。在异步情况下,事件将放在JS队列上,当前代码将首先运行到完成。在同步情况下,事件不会放在JS队列上,而是像函数调用一样执行。因此,事件的处理作为调用堆栈上的附加调用进行,之后代码将恢复,就像从正常函数调用返回后一样:这是同步行为


这里我忽略了的概念,这意味着执行异步代码有不同的优先级。

您指的是JavaScript事件循环

要回答您的问题,即为什么调度(也称为处理消息队列中的项目)是同步进行的:JavaScript是单线程的,因此不可能同时处理两条消息

关于JS事件循环的一些额外信息:

在web浏览器中,每当事件发生并出现时,都会添加消息 是附加到它的事件侦听器。如果没有侦听器,则 事件丢失。因此,使用单击事件处理程序单击元素 将添加一条消息——与任何其他事件一样

取自

这是一个不同的观点,从 :

JavaScript运行时包含一个消息队列,其中存储 要处理的消息及其关联的回调函数。 这些消息排队以响应外部事件(例如 单击鼠标或接收对HTTP请求的响应) 给定一个已提供的回调函数。例如,如果用户 我们要单击一个按钮,但没有提供回调函数–没有 消息将被排队

下面是关于同步处理消息队列中的项目的部分:

在循环中,为下一条消息轮询队列(每次轮询 称为“勾号”),当遇到消息时 执行该消息的回调


最后:

理论上,it事件是异步处理的,这有什么区别吗


完全是。如果您希望在某个地方记录三条队列消息
1
2
3
,那么它可能会以另一种顺序记录序列,如
2
1
3

您有一个非常原始的“doNothing”实现。有多少个队列,以及您是将它们视为Web API的一部分还是JS引擎的一部分,这完全取决于实现。您所说的“大多数事件在发生用户事件时是同步处理的”是什么意思?所有的JS代码都被阻塞了。谢谢你的回答,不过我还是不清楚。请看一看