为什么在几乎没有阻塞操作的情况下,事件循环从JavaScript开始就存在

Why the event loop existes from the beginning of JavaScript when there were almost no blocking operations

我正在尝试了解 JavaScript 运行时如何使用其单线程模型。有一个事件循环将阻塞操作(I/O 大多数)移动到运行时的不同部分,以保持主线程的清洁。顺便说一下,我觉得这个模型很有新意。

我假设这个模型自创建以来就是 JavaScript 的一部分,并且大多数阻塞 I/O 操作,例如 AJAX 调用 "discovered" 大约 5 年后来,那么一开始如果几乎没有阻塞操作,那么单线程非阻塞模型的动机是什么,并且该语言仅用于验证表单和动画屏幕。是长远眼光还是运气?

正如您已经说过的,事件循环用于应对缓慢的 I/O - 或者更一般地说, 操作不涉及代码运行的其他地方发生的 CPU需要此类操作的结果

但是I/O不仅仅是网络和磁盘! I/O 比任何设备都慢得多:计算机与 人类 !

通信

GUI 输入——点击按钮、输入文本,一切都很缓慢,因为计算机在等待用户输入。您的代码需要来自外部源的数据(外部形式 CPU 代码运行)。

GUI 事件是基于事件编程的主要原因。想一想:您将如何同步进行 GUI 编程? (您可以通过 OS 使用抢占 - 如下所述) 您不知道用户何时会单击按钮。基于事件的编程是这个特定任务的最佳选择(我们知道)。

此外,一个要求是只有一个线程,因为并行编程是困难的,Javascript 是为了 "normal users"。

这是一个不错的博客 post 我刚找到:

http://www.lanedo.com/the-main-loop-the-engine-of-a-gui-library/

Modern GUI libraries have in common that they all embody the Event-based Programming paradigm. These libraries implement GUI elements that draw output to a computer screen and change state in response to incoming events. Events are generated from different sources. The majority of events are typically generated directly from user input, such as mouse movements and keyboard input. Other events are generated by the windowing system, for instance requests to redraw a certain area of a GUI, indications that a window has changed size or notifications of changes to the session’s clipboard. Note that some of these events are generated indirectly by user input.




我想补充一点:

我们有两个主要选项来处理您的代码必须等待外部事件的问题(即无法在 CPU 您的代码 运行 中计算或检索的数据来自直接连接的 RAM - 任何会使 CPU 无法继续处理您的代码的东西):

  • 活动
  • Preemption被一个"higher power"喜欢的操作系统。

在后一种情况下,您可以编写顺序代码,OS 将检测您的代码何时需要尚不存在的数据。它将停止执行您的代码并将 CPU 提供给其他代码。

从某种意义上说,Javascript 中无处不在的基于事件的范例是一种倒退:为所有事情编写大量事件处理程序与仅按顺序写下您想要的内容并让 OS 负责管理资源 "CPU"。

我注意到,当我的基于事件的编程用于 GUI 时,我从来不想抱怨 - 但当我不得不为磁盘和网络进行编程时 I/O 我突然意识到它需要付出多少努力与让 OS 在后台处理此事件相比,所有事件处理。

我的理论:在事件处理程序中应对人类(他们的行为)感觉自然,这是软件之后的全部目的所有(基于 GUI 的软件)。但是当我不得不为 devices 做所有基于事件的事情时,感觉很不自然——我必须在我的编程中适应硬件?

从某种意义上说,出现在我们面前的基于事件的编程是从以前的“第四代语言”梦想中迈出的一步,回到更多面向硬件的编程——为了机器效率,而不是程序员效率。习惯编写基于事件的代码需要很多时间。同步编写并让 OS 负责资源管理实际上更容易 - 除非您已经习惯了基于事件的代码,以至于您现在对其他任何事情都有下意识的反应。

但想一想:在基于事件的编程中,我们让物理细节(例如我们的代码在何处执行以及从何处获取数据)决定了我们如何编写代码。我们没有专注于我们想要什么,而是更多地关注 如何 我们希望它完成。这是从抽象到硬件的一大步。

我们现在正在慢慢开发和引入可以帮助我们解决这个问题的工具,但即使像承诺这样的事情仍然需要我们思考 "event based" - 我们在有事件的地方使用这样的结构,即我们必须知道休息时间。所以我看不出有多大收获,因为我们仍然必须以不同的方式编写具有这种 "breaks" 的代码(即留下 CPU)。