Javascript 调用堆栈&;事件循环-为什么要等待空堆栈?

Javascript 调用堆栈&;事件循环-为什么要等待空堆栈?,javascript,v8,event-loop,Javascript,V8,Event Loop,我知道当调用堆栈为空时,消息从队列进入调用堆栈。若事件循环可以将消息从队列直接推送到调用堆栈而无需等待,这不是更好吗?这种行为背后的原因是什么?如果事件循环将在准确的时间推送消息,我们可以始终依赖函数,如setTimeout等 setTimeout(()=>console.log(“我想记录10毫秒,但我永远不会:(”),10); //一些阻塞操作 对于(设i=0;i

我知道当调用堆栈为空时,消息从队列进入调用堆栈。若事件循环可以将消息从队列直接推送到调用堆栈而无需等待,这不是更好吗?这种行为背后的原因是什么?如果事件循环将在准确的时间推送消息,我们可以始终依赖函数,如setTimeout等

setTimeout(()=>console.log(“我想记录10毫秒,但我永远不会:(”),10);
//一些阻塞操作
对于(设i=0;i<500000000;i++){
Math.random()*2+2-3;
}

console.log(“我将首先被记录lol”);
这里的V8开发者。这个问题似乎是基于对“调用堆栈”是什么的误解:它不是一个任何人都可以将东西推到的数据结构。相反,它是一个术语,表示一组函数相互调用时的当前状态。“推”的唯一方式调用堆栈上的另一个函数是当前正在执行的函数调用它的时间。如果事件系统在随机位置将随机调用插入到函数中,这将导致一个非常奇怪的编程模型

您可以设计一个概念上类似的编程环境,但它不会将任何东西推到调用堆栈上,而是中断和挂起当前正在执行的任何东西,并执行一个
setTimeout
-调度函数(或事件处理程序,等等)您必须解决的一个问题是:如果重复执行,即如果调度函数被另一个调度函数中断,而另一个调度函数又被另一个调度函数中断,等等,该怎么办?如果一个调度函数要花很长时间才能完成,该怎么办:以前执行的代码何时才能完成要再次取得进展?此外,虽然这可以在单线程世界中完成,但随机中断是并发的(从一致性的角度来看,这相当于并行/多线程),因此您需要同步原语,如锁(本质上,函数有一种方式说“不要中断此部分”--这反过来意味着您实际上无法保证调度请求的准确性).不要低估所有这些都会给程序员带来的复杂性成本:在编写代码时,他们必须记住,任何东西都可能在任何时候被中断,而另一方面,一个函数可能要处理的任何数据可能还没有准备好,因为生成它的另一个函数尚未完成运行


简而言之,JavaScript的事件循环系统就是这样,因为该语言避免了并发,而随机中断函数以执行其他函数就是并发,即使在单线程系统上也是如此。

我知道它为什么会这样工作。我想知道架构为什么会以这种方式实现让多线程实现你的建议?<代码> SETTIMEOUT 保证它的代码直到10毫秒通过才运行。在读取之后不完全是10ms。你应该从一个不同的角度考虑你的问题:阻塞操作意味着什么?);它确实需要多个线程,即将处理控制推迟到更高的权限(如操作系统)。因此,我猜想它是以这种方式实现的,以便在没有线程处理逻辑及其大部分陷阱的情况下进行必要的事件驱动编程。并在10天内建成。谢谢你的解释。现在对我来说这很有意义。你知道关于这个主题的更多信息吗?我想了解更多有关事件循环的技术细节,以及消息是如何从队列进入堆栈的。您可以将“事件循环”视为等待调用的闭包列表。当控件返回到事件循环(即,先前调用的闭包已返回)时,将调用下一个等待的闭包。这将启动一个新的调用堆栈(如上所述,“调用堆栈”不是一个数据结构,它只是描述函数相互调用的事实,形成一个类似堆栈的控制流)。