据我了解,在执行回调队列中的项目之前,需要满足两个条件:
我了解背后的原因,例如,如果在全局执行上下文中调用了setTimeout
,但是如果在本地执行上下文中调用了setTimeout
,则为什么第二个条件是必要的?我们不是应该只等到弹出所有{strong>上方位于setTimeout
的本地执行上下文的帧吗?
答案 0 :(得分:1)
我认为主要的误解在于此处的“调用堆栈”:让我们来做一下:
(function A() {
(function B() {
setTimeout(function C() {
(function D() { })();
});
})();
})();
首先,代码被初始化,A将被调用,B将被调用,调用堆栈如下所示:
[init] -> A -> B
现在设置超时时间。由于没有剩下任何代码,因此调用栈展开,然后变为空。
现在一段时间后,计时器将触发回调:
[timer] ->
然后它将调用C:
[timer] -> C
在C内,D将被称为:
[timer] -> C -> D
由于没有剩下任何代码,因此调用栈再次展开。如您所见,A和B不再位于调用栈中,它们很久以前就离开了它。因此
在本地执行上下文中调用了setTimeout。我们不是应该只等到弹出setTimeout被调用的本地执行上下文上方的所有帧吗?
没有什么意义,因为“上下文是setTimeout”是在 的最高执行上下文中执行的。
请注意,执行上下文确实具有父执行上下文,该生存上下文的生存时间与其子生存时间(关闭)一样长,但是与调用栈无关。