如何连接事件循环,回调队列和Javascript的单线程?

kur*_*ett 20 javascript asynchronous event-loop event-queue single-threaded

一般目标

我想知道以下javascript环境如何作为系统互连.

  • Javascript引擎
  • 事件循环
  • 事件队列

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

我(相信)理解的事情:

  • Javascript是单线程的,因此只有一个callstack.

  • Javascript环境只提供一些真正异步的函数.这些可能包括setTimeout(),setInterval()和I/O函数.

  • 如果不使用其中一个,开发人员就无法创建自己的异步函数.
  • Javascript本身同步运行,但通过它的异步函数可以在当前的callstack清除后回调可能的阻塞函数.

例:

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

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

      console.log(‘Sync code finished…')
Run Code Online (Sandbox Code Playgroud)

示例步骤:

(如果我错了,请纠正步骤)

  1. 记录"同步代码已启动..."
  2. setTimeout被添加到堆栈但立即返回控件
  3. setTimeout被发送到另一个'thread'...'worker'?在javascript的单线程之外计算2000毫秒
  4. 记录"同步代码已完成..."
  5. 在2000毫秒之后,asyncLog()被推送到事件队列
  6. 由于callstack已清除,因此Event Loop会检查事件队列是否有待处理的回调
  7. asyncLog()从队列中删除,并由事件循环推送到堆栈
  8. 记录了"异步功能已完成"
  9. callstack现在很清楚了

质询

如果有人可以概述async函数(例如setTimeout)从第一次访问callstack到回调到callstack的时间和位置的步骤的概述,则不需要逐个回答这些步骤.

  1. 在第3步,谁产生这个新线程?是浏览器吗?
    • 这个新线程被阻止正确吗?
    • 如果你有一个创建1000 setTimeouts的循环会发生什么.是否创建了1000个"线程"?
    • 一次可以生成多少个线程是否有限制?
    • 当新线程完成执行时,它如何最终在队列中?
  2. 谁提供了事件队列?
  3. 谁提供事件循环?
    • 事件循环是否轮询事件队列?
    • javascript的线程是否知道事件循环?或者Event循环只是把东西推到堆栈上?
    • 事件循环如何知道堆栈何时清除?

Ber*_*rgi 12

你的理解和你的例子似乎基本上是正确的.现在,问你的问题:

在第3步,谁产生这个新线程?是浏览器吗?

是.它基本上是为那些"真正异步"功能提供实现的东西.IIRC,setTimeout直接在JS引擎中实现,而网络IO肯定是浏览器的责任 - 但创建它们并不重要.最后,在您的"浏览器环境"中,它始终是浏览器的一部分.

这个新线程被阻止正确吗?

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

如果你有一个创建1000 setTimeouts的循环会发生什么.是否创建了1000个"线程"?

可能.但不太可能.我假设那些真正需要自己的线程的异步操作,使用线程池,并且请求排队.此池的大小可能隐藏在浏览器配置的大小中.

一次可以生成多少个线程是否有限制?

这将由操作系统控制.

当新线程完成执行时,它如何最终在队列中?谁提供了事件队列?

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

谁提供事件循环?事件循环是否轮询事件队列?

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

javascript的线程是否知道事件循环?或者Event循环只是把东西推到堆栈上?

我会说javascript 事件循环线程中运行.事件循环只是反复弹出队列中的事件并执行他们的javascript.

事件循环如何知道堆栈何时清除?

事件循环调用 javascript执行 - 因此当javascript返回时堆栈是清除的.

  • 我花了一段时间才意识到这些都是我的问题的好答案.我觉得浏览器如何处理JS引擎的一些很好的图形将大大有益于社区.Phillip Roberts关于事件循环的讨论在许多方面也非常有用.https://www.youtube.com/watch?v=8aGhZQkoFbQ (3认同)