2015-11-05 49 views
0

我有以下代码:使用Javascript - 事件侦听器的引擎盖下是如何工作的

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

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

sayHiLater(); 

我想更好地了解事件侦听器的引擎盖下是如何工作的, 所以在我上面的例子,如setTimeout的是被执行,真的发生了什么? 我知道它会创建一个新的执行上下文,但我的问题是;那执行上下文是简单地延迟了3秒,这意味着执行堆栈正在移动到其他事物,同时3秒结束它回到执行上下文,或者它只是传递给浏览器引擎某种形式的匿名函数参数引用,告诉它什么时候触发,然后马上将setTimeOut执行上下文从执行堆栈中弹出。或者我距离真正发生的事情还有很远的距离。感谢您的时间。

+1

简单的实现可能是:将事件发布到事件队列中 - >让执行者从事件队列中拉第一个事件 - >让执行者寻找evnet回调(从一个地图) - >执行事件回调 –

+0

我删除了我的答案,因为我看到这个问题的可能重复:http://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions – ambodi

回答

0

难道仅仅传递给浏览器引擎某种匿名函数参数的引用,告诉它何时启动,然后马上将setTimeOut执行上下文被弹出执行堆栈。

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

然后,当前轮完成并且不再执行任何代码后,引擎返回到事件循环并等待发生某些事情。 3秒后,时间已准备好触发回调,并且当没有其他代码正在执行时,事件循环启动匿名功能。
所以setTimeout并不真的打电话它的回调,它只有时间表它为以后。当定时器用完时,它将被事件循环本身调用。

注意的是被放置在计时器匿名功能是sayHiLater一个closure(它关闭在greeting变量),所以变量环境(“范围”)将被保留(未垃圾收集)即使在sayHiLater执行上下文从堆栈弹出,直到回调将被执行。

+0

嘿,以及你上面的人说,执行上下文没有结束,但执行堆栈只是移动到下一个东西,直到3秒钟过去,然后回到它(如果没有其他东西在堆栈上)并执行该函数 – RunningFromShia

+0

我指的是@ambodi注释。 – RunningFromShia

+0

@ user2081462:他可能不知道他在说什么:-)你的意思是哪个执行上下文,全局的,'sayHiLater()','setTimeout(...)'或者anon回调的呢? – Bergi