【问题标题】:Javascript - how event listeners work under the hoodJavascript - 事件监听器如何在后台工作
【发布时间】:2016-02-06 06:49:54
【问题描述】:

我有以下代码:

function sayHiLater(){
    var greeting = "Hi!";
    setTimeout(function() {
        console.log(greeting);

    }, 3000); 
    console.log("Hello before hi");
}

sayHiLater();

我想更好地了解事件侦听器的工作原理, 所以在我上面的例子中,当 setTimeOut 被执行时,到底发生了什么? 我知道它创建了一个新的执行上下文,但我的问题是;执行上下文是否只是被延迟了 3 秒,这意味着执行堆栈同时移动到其他事物,并且随着 3 秒的结束,它又回到了该执行上下文,或者它只是传递给浏览器引擎匿名函数参数的某种引用,告诉它何时触发,然后立即将 setTimeOut 执行上下文从执行堆栈中弹出。或者我只是完全远离真正发生的事情。感谢您的宝贵时间。

【问题讨论】:

  • 简单的实现可能是:将事件发布到事件队列中 -> 让执行者从事件队列中拉出第一个事件-> 让执行者寻找 evnet 回调(比如说,一张地图) -> 执行事件回调
  • 我删除了我的答案,因为我看到这个问题可能重复:stackoverflow.com/questions/12930272/…

标签: javascript function events listener


【解决方案1】:

它是否只是将某种匿名函数参数的引用传递给浏览器引擎,告诉它何时触发,然后立即将setTimeOut 执行上下文从执行堆栈中弹出。

是的,这正是正在发生的事情。 setTimeout 执行上下文立即返回(并跳转到下一条语句,您的 console.log)。

然后在您当前的回合完成并且没有更多代码要执行后,引擎将返回事件循环并等待某些事情发生。 3 秒后,准备触发回调,当没有其他代码执行时,事件循环启动匿名函数。
所以setTimeout 并没有真正调用它的回调,它只是调度它以备后用。当计时器用完时,它会被事件循环本身调用。

请注意,放在计时器上的匿名函数是closure(它关闭了greeting 变量),因此sayHiLater 的变量环境(“范围”)将被保留(不是垃圾-收集)即使在 sayHiLater 执行上下文从堆栈中弹出之后,直到回调将被执行。

【讨论】:

  • 嘿,你上面的那个人说执行上下文还没有结束,但是执行堆栈只是移动到下一件事,直到3秒过去,然后它又回到它(如果堆栈上没有其他内容)并执行该匿名函数
  • 我指的是@ambodi 的评论。
  • @user2081462:他可能不知道他在说什么 :-) 你指的是哪个执行上下文,全局上下文,sayHiLater()s 一个,setTimeout(…)s 一个还是匿名回调的一个?
  • 我说的是 setTimeout 执行上下文——一旦你将参数传递给它并执行它,一个新的执行上下文就会发生。我的问题是 - javascript 会简单地启动执行上下文,看到有 3 秒的延迟,然后继续做其他事情,然后在 3 秒过去后返回 setTimeout 的执行上下文吗?或者是另一回事。顺便说一句,我很想知道这是否适用于所有事件监听器。
  • 执行上下文是“堆栈帧”。它仅在通话期间存在。由于 JS 的单线程特性,以及它的同步运行到完成(每个 eventloop 循环)模型,它们通常不会存在很长时间。不确定“还没有结束”应该是什么意思
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 2020-06-21
  • 1970-01-01
  • 2023-02-07
  • 2012-02-15
  • 2016-07-30
相关资源
最近更新 更多