我了解到javascript是单线程的,并且任何异步任务仅在当前堆栈为空之后才执行。 setTimeout
承诺,仅在当前功能完成后才执行。
我想知道浏览器在执行某些事件时如何调用事件处理程序函数。
当我们说要注册一个事件时,该在哪里注册? (消息队列,作业队列)?它在哪里保存在内存中,浏览器如何知道某个事件已发生?
与操作系统相关的事件会调用吗?
我已经看过philip roberts video,并且了解了事件循环的功能。
我想了解javascript的内部原理。
答案 0 :(得分:1)
当我们说要注册一个事件时,该在哪里注册?它在哪里保存在内存中?
处理程序功能安装在您正在侦听的资源上。对于DOM事件,它是浏览器用于显示文档的DOM对象,用于保证它是JS对象,对于计时器,则有一个内部计时器对象(与DOM有关,因为计时器是在HTML和每个窗口中定义的)。
(消息队列,作业队列)?
否,注册事件处理程序时,这些内容将保持空白。仅当事件实际发生时,需要运行的处理程序才会进入队列。
浏览器如何知道某个事件已发生?与操作系统有关的事件会调用吗?
是的,最终事件是来自操作系统的,无论是网络数据包到达,发生超时还是在浏览器窗口上单击。 (只有很少的事件是从浏览器内部触发的)。然后,浏览器会检查哪些资源受系统事件影响(例如,单击了哪个DOM元素),然后触发相应的事件,以便可以根据需要安排任何处理程序。
答案 1 :(得分:1)
浏览器主线程是一个事件循环。这是一个无限循环,可保持进程正常运行。它等待事件并对其进行处理。这里的事件表示几种事情,例如:
例如,这是主事件循环的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();
那么,这里发生的是以下情况:
有关一般如何在浏览器和浏览器引擎中实现事件循环的更多实际说明,请参见Reference。