在NodeJs和JS中将什么函数放入EventLoop

时间:2014-02-06 07:01:50

标签: javascript node.js asynchronous event-driven event-loop

我一直在阅读一些NodeJs文章,以了解它的异步性,在此期间我发现了这个并且非常喜欢它Node.js, Doctor’s Offices and Fast Food Restaurants – Understanding Event-driven Programming

有一个名为EventLoop的东西是基于FIFO的队列。他们说当异步函数被击中时,它会被放到EventLoop并继续在那里执行。

我在这里有点困惑。例如,据说是here

  

实际上,像setTimeout和setInterval这样的异步函数是   推到一个称为事件循环的队列。

并在同一篇文章中:

  

Event Loop是一个回调函数队列。当一个异步   函数执行后,回调函数被推入队列。该   JavaScript引擎在开始之前不会开始处理事件循环   执行异步函数后的代码。

但它与此图像不同:

enter image description here

让我们看看下面的例子:

console.log("Hello,");
setTimeout(function(){console.log("World");},0);

从我从那些不同的解释中理解,

  1. 第一个说function(){console.log("World");}函数的setTimeout()部分,即回调,将放在EventLoop中。完成setTimeout后,它也会执行EventLoop
  2. 另一个说,整个事件setTimeout(function(){console.log("World");},0);将被放入EventLoop并将被执行......
  3. 我现在更加困惑了。它应该是简单的东西,但我想一个好但简单的解释对我来说对以下问题很好:

    1. 上述哪一项是真的?
    2. 什么是EventLoop?一个类比,一个方法,对象等真实的东西?
    3. 如果我想从头开始实现与EventLoop类似的东西,它会如何简单?也许有些代码会很高兴看到。

4 个答案:

答案 0 :(得分:6)

将Node的事件循环视为在客户端循环的“主要功能”(除了Node在服务器端,您在技术上不需要代码中的事件循环) ,因为它基于事件:)。

考虑连接作为JS对象的每个客户端,它再次运行您的代码,在它自己的地址空间中,使用它自己的变量,但在完全相同的过程中,和相同的CPU 一样你的程序的其余部分(你可以聚集这个,但一般来说这就是开箱即用的方式)。

工作线程是阻塞I / O被分割成的东西,并且通过插件,您甚至可以将工作线程分散到不同的节点服务器(文件I / O,数据库I / O,网络访问等),所有这些都被放入工人线程。)

How Node works

当你创建的事件被放入一个队列时,当它被执行时,它会在主事件循环(类型)中运行,但更重要的是,事件本身被放置在事件循环中(将调用它的触发器) )。

这是V8引擎的所有部分(即事件循环)。是什么让Node如此出色,它让数十万个客户端进入同一个循环,并隔离了阻塞I / O.

主要的一点是:如果需要做某些事情,节点总是会做点什么。

与其他框架一样,I / O会阻止其余代码的执行。

Blocking vs Non-Blocking I/O

基本上,几乎所有你通常写的东西都会在事件循环中发生,但不完全是。什么意思发生在你的代码运行一次,然后它只是插入事件,然后退出。

这有意义吗?

  

因此,当您的代码完成运行时,您排队的所有事件,   (例如,包括更多代码)仍然驻留在事件中   循环。

节点与其他一切非常不同,但这是一个非常好的解释,可以帮助您入门。

如果你感兴趣,我写了很多关于Quora的细节...... https://www.quora.com/How-good-is-Node-js

答案 1 :(得分:4)

我将根据MDN关于Event Loops的少量信息尝试回答。请注意,此答案仅适用于JavaScript,不适用于Node。

从它的声音来看,令人困惑的是你的第二句话应该写得更清楚,例如:

  

Event Loop是一个回调函数队列。执行异步函数时,回调函数将被推入队列。 JavaScript引擎不会启动 继续处理事件循环,直到执行异步函数后的代码。

如果是这种情况,那么它会更加一致。所有回调,当它们触发时,都被输入FIFO队列,并按顺序运行。即,如果一个事件被触发,则下一个事件将在第一个事件完成之前触发。

我上面链接的MDN参考甚至包括事件循环的伪代码:

while(queue.waitForMessage()){
    queue.processNextMessage();
}

定时器和间隔被定义为HTML规范中DOM的一部分。在我对该规范的快速检查中,我找不到任何对“消息循环”的直接引用。

答案 2 :(得分:3)

第二种解释是假的 - 在JavaScript中没有自动将“整体”事物放在事件循环中的机制。您的第一个理解是正确的,您可以将事件队列描述为一系列回调。事件循环的“迭代”执行队列中的下一个回调并将其删除。允许回调对更多回调进行排队,依此类推。

事件循环还会检查外部事件,例如网络活动,用户活动或基于计时器的事件,并为这些操作调度适当的回调。因此,除非应用程序关闭,否则事件循环永远不会退出。如果目前无事可做,那只会等待发生一些事情。

答案 3 :(得分:2)

基于LIBUV和LIBIO的NodeJS事件循环,请参阅此链接https://github.com/joyent/libuv

我也不清楚这一点,我知道一点点,

事件循环:

步骤1:我向Nodejs发送请求意味着从数据库中读取文件;        但是数据库已经在使用中(所以将此请求放入事件循环中)

步骤2:此时nodejs接收其他请求意味着套接字请求        注意:DataBase操作现在只忙,不是socket所以它的执行套接字操作

步骤3:接收多个请求并放置到事件循环,然后根据I / O执行

I / O: 例如:

   someoFileperation(callback)
    {
          //callback message i am finished any other related process in event loop
           }

   Next process:
    someSocketOperation(calback)
        {
           //Callback message i am finished my socket operation any other related process in Event loop
              }