Javascript 收听JS中的事件

Javascript 收听JS中的事件,javascript,asynchronous,event-loop,Javascript,Asynchronous,Event Loop,我听过很多关于JS是如何单线程和异步的,我也知道事件循环和回调队列 我不明白的是,单线程语言在执行其他代码时,如何监听事件并向队列中添加事件处理程序? 例如,在长循环运行时单击按钮,即使线程已被占用,也会将其回调添加到队列中 谢谢答案是操作系统(或Javascript,用于代码生成的事件)将事件发送到浏览器中的JS,这些事件被放入队列中进行处理。Javascript的一个线程将事件从队列中移除并处理它们,直到没有剩余事件,然后等待下一个事件到来。有关更多信息,请阅读消息队列:简单地说,浏览器不是

我听过很多关于JS是如何单线程和异步的,我也知道事件循环和回调队列

我不明白的是,单线程语言在执行其他代码时,如何监听事件并向队列中添加事件处理程序?

例如,在长循环运行时单击按钮,即使线程已被占用,也会将其回调添加到队列中


谢谢

答案是操作系统(或Javascript,用于代码生成的事件)将事件发送到浏览器中的JS,这些事件被放入队列中进行处理。Javascript的一个线程将事件从队列中移除并处理它们,直到没有剩余事件,然后等待下一个事件到来。有关更多信息,请阅读消息队列:

简单地说,浏览器不是用javascript编写的,javascript也不是处理事件的工具

UI事件首先由操作系统发送给浏览器,然后浏览器将处理这些消息,并将任务排队以构建DOM事件并将其分派,相关JavaScript回调最终可能会触发

只有最后一部分涉及JavaScript。您很可能有一个用户代理(UA),它不实现JavaScript,但仍然处理一些UI事件(例如CSS指针事件、HTML输入、媒体控件等)

如何处理将取决于UA

很长一段时间以来,在您给出的示例中,浏览器无法处理在事件循环繁忙时触发的点击(IIRC最新IE仍然无法处理)。只有在现代浏览器中,他们才开始使用能够通过共享不同消息队列进行通信()的浏览器

因此,即使执行事件循环的各种任务的“主”渲染器线程很忙,例如执行js,其他进程仍然可以并行运行,并将新任务排入相应的任务队列。

当渲染器线程完成其长任务时,一个新任务已经排队,它可以处理它。

因为,为了更好的类比,这就像一个服务员向B表发送订单,然后停下来从C表接受订单,在返回厨房的路上,浏览a表,看看他们是否需要处理。所有这些操作都是串行执行的(即在一个线程中),但通过不断检查和重新检查,同一个服务员能够处理表a、B和C。@Rounin JS引擎也会不时暂停循环的执行(在我的示例中),以检查是否发生了任何事件,将其回调排队,然后继续循环?它不会暂停,否。“事件循环会持续检查调用堆栈,以查看是否有任何需要运行的函数。”请参阅:这是否意味着操作系统知道浏览器内部发生的事件,像按钮或DOM中被单击的任何元素一样?不。我的理解是,操作系统只发送非常基本的UI事件——鼠标/键向上/向下,鼠标在x,y坐标下移动鼠标事件。应用程序/浏览器在其上下文中解释这些事件。