Event Loop、Callback Queue、Javascript的单线程是怎么连接的?

How are the Event Loop, Callback Queue, and Javascript’s single thread connected?

总体目标

我想知道 javascript 环境的以下部分 如何作为一个系统互连

我们可以将其限制在浏览器环境,因为节点已在另一篇文章中介绍过(here)

我(相信)理解的事情:

示例:

      console.log(‘Sync code started…’);

      setTimeout(function asyncLog() {
           console.log(‘Async function has completed’)
      }, 2000);

      console.log(‘Sync code finished…')

示例步骤:

(如有错误请指正)

  1. “同步代码已启动...”已记录
  2. setTimeout 被添加到堆栈但立即 returns 控制
  3. setTimeout 被发送到不同的‘thread’…‘worker’?在 javascript 的单线程之外计算 2000 毫秒
  4. 记录“同步代码完成...”
  5. 2000 毫秒后,asyncLog() 被推送到事件队列
  6. 因为调用栈是清空的,事件循环检查事件队列中是否有待处理的回调
  7. asyncLog() 从队列中移除并通过事件循环推入堆栈
  8. 记录“异步功能已完成”
  9. 调用堆栈现在清晰

问题

如果有人可以概述异步函数(例如 setTimeout)从第一次到达调用堆栈到被调用的步骤和步骤,则无需一一回答回到调用堆栈。

  1. 在第 3 步,谁产生了这个新线程?是浏览器吗?
    • 这个新线程被阻止对吗?
    • 如果您有一个创建 1000 个 setTimeout 的循环,会发生什么情况。是否创建了 1000 个“线程”?
    • 一次可以生成多少线程有限制吗?
    • 当新线程完成执行时,它如何在队列中结束?
  2. 谁提供事件队列?
  3. 谁提供事件循环?
    • 事件循环是否轮询事件队列?
    • javascript 的线程是否知道事件循环?还是事件循环只是将东西压入堆栈?
    • 事件循环如何知道堆栈何时清空?

你的理解和你的例子基本正确。现在,回答您的问题:

On step 3, who produces this new thread? Is it the browser?

是的。它基本上是为那些 "truly asynchronous" 函数提供实现的东西。 IIRC,setTimeout 直接在 JS 引擎中实现,而网络 IO 绝对是浏览器的责任——但谁创建它们并不重要。最后,在您的 "browser environment" 中,它始终是浏览器的一部分。

This new thread is being blocked correct?

是的。不,这取决于需要完成的工作,即您调用了哪个异步函数。有些可能需要旋转一个新线程,但对于简单的超时,我很确定使用了非阻塞系统调用。

What happens if you have a loop that creates 1000 setTimeouts. Are 1000 ‘threads’ created?

有可能。不过不太可能。对于那些真正需要自己线程的异步操作,我会假设使用了线程池,并且对请求进行了排队。此池的大小可能隐藏在浏览器配置的内部。

Is there a limit to how many threads can be spawned at a time?

那将由 OS 控制。

When new thread finishes executing, how does it end up on the queue? Who supplies the Event Queue?

基本上,每个这样的线程的最后一个动作是将其结果放入事件队列。

Who supplies the Event Loop? Does the event loop poll the Event Queue?

我想说这是一个实现细节,无论是循环轮询队列还是队列驱动循环迭代。

Is the javascript’s thread aware of an event loop? Or does the Event loop just push things onto the stack?

我会说 javascript 在 事件循环线程中运行 。事件循环只是重复地从队列中弹出事件并执行它们的 javascript.

How does the Event loop know when the stack is clear?

事件循环 调用 javascript 执行 - 因此当 javascript returns.

时堆栈是清空的