javascript - 没有无限的while循环,还有其他方法可以实现 “listening”函数吗?

标签 javascript reactjs loops events rethinkdb

我一直在思考诸如React之类的代码和库,这些代码和库会在事件发生时自动对事件使用react,并且想知道如何在较低级别的C++和机器代码上实现所有这些功能。

我似乎无法弄清楚是否可以通过其他线程上运行的while循环来实现类似事件监听器的其他方式。

那么这一切都在幕后吗?只是循环一直向下吗?例如,像RethinkDB,它宣传自己为具有repubsub库的“实时数据库”。 “订阅”方法是否只是在幕后使用while循环实现的?我似乎找不到任何信息。

就像插座和东西一样。当计算机正在“侦听”套接字连接的端口时,该计算机是否正在运行类似以下内容的内容:

while(1) {
    if (connectionFound) {
        return True;
    }
}

还是我想念的东西?

最佳答案

I've written the answer to this question as an aside in another answer. Normally I'd close this question as a duplicate and point to that answer however this is a very different question. The other question asked about javascript performance. In order to answer that I had to first write the answer to this question.

As such I'm going to do something that's not normally supposed to be done: I'm going to copy part of my answer to another question. So here's my answer:


javascript和node.js等待的实际事件根本不需要循环。实际上,它们需要0%的CPU时间。
异步I / O的工作方式(任何编程语言)
硬件
如果我们真的需要了解节点(或浏览器)内部的工作方式,那么不幸的是,我们必须首先了解计算机的工作方式-从硬件到操作系统。是的,这将是一次深潜,请耐心等待。
一切始于中断的发明。

It was a great invention, but also a Box of Pandora - Edsger Dijkstra


是的,以上引用来自同一“Goto认为有害” Dijkstra。从一开始就将异步操作引入计算机硬件被认为是一个非常困难的话题,即使对于业内的一些传奇人物而言。
引入了中断以加快I / O操作。硬件不需要将软件以无限循环的方式轮询某些输入(从而节省了CPU时间来完成有用的工作),而是向CPU发送信号以告知事件已发生。然后,CPU将挂起当前正在运行的程序并执行另一个程序来处理中断-因此我们将这些函数称为中断处理程序。单词“处理程序” 一直一直停留在GUI库中,该库将回调函数称为“事件处理程序”。
Wikipedia实际上有一篇不错的文章,关于中断,如果您不熟悉它并想了解更多:https://en.wikipedia.org/wiki/Interrupt
如果您一直在关注,您会注意到中断处理程序的概念实际上是回调。您将CPU配置为在事件发生后的某个时间调用函数。因此,即使回调也不是一个新概念-它比C更旧。
操作系统
中断使现代操作系统成为可能。没有中断,CPU将无法暂时停止程序以运行OS(嗯,这是协作式多任务处理,但现在暂时忽略它)。操作系统的工作方式是在CPU中设置硬件计时器以触发中断,然后告诉CPU执行程序。运行您的操作系统的正是此定时定时器中断。
除了计时器外,操作系统(或更确切地说是设备驱动程序)还为I / O设置了中断。发生I / O事件时,操作系统将接管您的CPU(或多核系统中的一个CPU),并检查其数据结构以处理下一步处理I / O的过程(这称为抢先式多任务处理)。
从键盘和鼠标存储到网卡的所有内容都使用中断来告诉系统要读取的数据。如果没有这些中断,监视所有这些输入将占用大量CPU资源。中断是如此重要,以至于它们通常被设计成USB和PCI等I / O标准。
工艺流程
现在,我们对此有了清晰的了解,我们可以了解节点/ javascript如何实际处理I / O和事件。
对于I / O,各种OS具有提供异步I / O的各种不同API-从Windows上的重叠I / O到Linux上的轮询/轮询,再到BSD上的kqueue到跨平台select()。 Node在内部将libuv用作这些API的高级抽象。
尽管细节不同,但这些API的工作方式相似。本质上,它们提供了一个函数,当调用该函数时,它将阻塞您的线程,直到OS向其发送事件为止。因此,是的,即使非阻塞I / O也会阻塞您的线程。这里的关键是阻塞I / O将在多个位置阻塞您的线程,但非阻塞I / O仅在一个位置(您等待事件的位置)阻塞线程。
请查看我对另一个问题的答案,以获取有关此类API在C / C++级别如何工作的更具体示例:I know that callback function runs asynchronously, but why?
对于诸如按钮单击和鼠标移动之类的GUI事件,只需跟踪鼠标和键盘中断,然后将其转换为UI事件即可。这样可以释放您需要知道按钮,窗口,图标等位置的软件表格。
这允许您执行的操作是以面向事件的方式设计程序。这类似于中断使OS设计人员实现多任务处理的方式。实际上,异步I / O对框架来说是对OS的中断。它允许javascript花费正好0%的CPU时间来处理(等待)I / O。这就是使异步代码快速的原因-并不是真的更快,但不会浪费时间等待。
该答案的期限很长,因此我将保留指向该主题相关其他问题的答案的链接:
Node js architecture and performance(注意:此答案提供了一些有关事件和线程之间关系的见解-tldr:操作系统在内核事件之上实现线程)
Does javascript process using an elastic racetrack algorithm
how node.js server is better than thread based server

关于javascript - 没有无限的while循环,还有其他方法可以实现 “listening”函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61262054/

相关文章:

javascript - 在 WordPress 中添加事件监听器

php - 在点阵打印机上打印简单的网页

javascript - 导航点击页面滚动的限制区域

reactjs - 类型 'token' 中缺少属性 'PropsWithChildren<WithUrqlProps>',但类型 '{ token: string; }' 中需要属性 0x104567910

java - 遍历具有不同长度延迟的文本

java - 需要将 ArrayList 中的整数存储在尽可能少的容器中

javascript - 每个输入的 Angular 表单验证类

打开 Chrome 开发工具后 Reactjs 应用程序会变慢

javascript - React.js 和 Radium.js - 使 React 样式本质上是全局的,但仍受用户输入的影响?

Python:循环中IF语句的处理不一致