事件处理程序如何在javascript中内部执行?

事件处理程序如何在javascript中内部执行?,javascript,asynchronous,message-queue,event-loop,Javascript,Asynchronous,Message Queue,Event Loop,我知道javascript是单线程的,任何异步任务都只能在当前堆栈为空后执行。回调,setTimeout,承诺仅在当前函数完成后执行 我想知道当我执行某些事件时,浏览器如何调用我的事件处理程序函数 当我们说我们正在注册一个事件时,我们在哪里注册它?(消息队列、作业队列)?它保存在内存中的什么位置?浏览器如何知道发生了某些事件 事件是否与操作系统调用相关 我已经看过了,并且理解了事件循环的功能 我想了解javascript的内部结构 当我们说我们正在注册一个事件时,我们在哪里注册它?它保存在内存中

我知道javascript是单线程的,任何异步任务都只能在当前堆栈为空后执行。回调,
setTimeout
,承诺仅在当前函数完成后执行

我想知道当我执行某些事件时,浏览器如何调用我的事件处理程序函数

当我们说我们正在注册一个事件时,我们在哪里注册它?(消息队列、作业队列)?它保存在内存中的什么位置?浏览器如何知道发生了某些事件

事件是否与操作系统调用相关

我已经看过了,并且理解了事件循环的功能

我想了解javascript的内部结构

当我们说我们正在注册一个事件时,我们在哪里注册它?它保存在内存中的什么位置

正在侦听的资源上安装了处理程序函数。对于DOM事件,浏览器用于显示文档的是DOM对象,对于JS对象,对于计时器,有一个内部计时器对象(与DOM相关,因为计时器是在HTML和每个窗口中定义的)

(消息队列、作业队列)

不,当注册事件处理程序时,这些将保持为空。只有当事件实际发生时,才将需要运行的处理程序放入队列

浏览器如何知道发生了某些事件?事件是否与操作系统调用相关


是的,最终事件来自操作系统,无论是网络数据包到达、发生超时还是在浏览器窗口上单击。(从浏览器机器本身内部触发的事件很少)。浏览器然后检查哪些资源受系统事件影响(例如,单击了哪个DOM元素),然后触发相应的事件,以便根据需要调度任何处理程序。

浏览器主线程是一个事件循环。这是一个无限循环,使过程保持活跃。它等待事件并处理它们。这里的事件意味着以下几类事情:

  • 用户已与UI组件交互(单击按钮、将鼠标悬停在某物上等…)
  • API请求已返回响应
  • 已完成访问操作系统资源的请求
例如,这是主事件循环的Firefox代码:

while (!mExiting)
    NS_ProcessNextEvent(thread);
假设我们有以下代码:

function jsFunction() {
    console.log("prints first");
    // execute remote API call
    axios.get("url").then(reponse => {
        console.log("success");
    }).catch(error => {
        console.log("error");
    });
    console.log("prints second");
}
我们称这个函数为:

jsFunction();
因此,这里发生的情况如下:

  • 您让执行此函数的单线程控制行打印“先打印”
  • 然后你有一个外部API调用,所以浏览器将它作为一个请求发送到你的操作系统的网络层,以执行http请求,并注册我们提供的回调函数,在响应来自网络层时执行,而不是等待它发生,它继续执行
  • 继续执行它打印“打印秒”
  • 当响应来自网络层时,事件循环将执行您提供的回调函数。此响应是向上述事件循环发出的事件。它执行适当的回调,并根据响应状态打印“成功”或“错误”

有关如何在浏览器和浏览器引擎中实现事件循环的更多实际说明,请参阅。

回调。。。仅在当前函数完成后执行。
不正确,回调通常立即执行。(即使使用
Promise
constructor)事件监听器也会在事件发生后被同步调用,IIRCyes回调也会立即执行,但我的问题的上下文与异步编程有关。我不是在询问我们用于普通函数参数的回调。