我一直在阅读一些NodeJs文章,以了解它的异步性,在此期间我发现了这个并且非常喜欢它Node.js, Doctor’s Offices and Fast Food Restaurants – Understanding Event-driven Programming
有一个名为EventLoop
的东西是基于FIFO的队列。他们说当异步函数被击中时,它会被放到EventLoop并继续在那里执行。
我在这里有点困惑。例如,据说是here:
实际上,像setTimeout和setInterval这样的异步函数是 推到一个称为事件循环的队列。
并在同一篇文章中:
Event Loop是一个回调函数队列。当一个异步 函数执行后,回调函数被推入队列。该 JavaScript引擎在开始之前不会开始处理事件循环 执行异步函数后的代码。
但它与此图像不同:
让我们看看下面的例子:
console.log("Hello,");
setTimeout(function(){console.log("World");},0);
从我从那些不同的解释中理解,
function(){console.log("World");}
函数的setTimeout()
部分,即回调,将放在EventLoop中。完成setTimeout
后,它也会执行EventLoop
。setTimeout(function(){console.log("World");},0);
将被放入EventLoop并将被执行...... 我现在更加困惑了。它应该是简单的东西,但我想一个好但简单的解释对我来说对以下问题很好:
答案 0 :(得分:6)
将Node的事件循环视为在客户端循环的“主要功能”(除了Node在服务器端,您在技术上不需要代码中的事件循环) ,因为它基于事件:)。
考虑连接作为JS对象的每个客户端,它再次运行您的代码,在它自己的地址空间中,使用它自己的变量,但在完全相同的过程中,和相同的CPU 一样你的程序的其余部分(你可以聚集这个,但一般来说这就是开箱即用的方式)。
工作线程是阻塞I / O被分割成的东西,并且通过插件,您甚至可以将工作线程分散到不同的节点服务器(文件I / O,数据库I / O,网络访问等),所有这些都被放入工人线程。)
当你创建的事件被放入一个队列时,当它被执行时,它会在主事件循环(类型)中运行,但更重要的是,事件本身被放置在事件循环中(将调用它的触发器) )。
这是V8引擎的所有部分(即事件循环)。是什么让Node如此出色,它让数十万个客户端进入同一个循环,并隔离了阻塞I / O.
主要的一点是:如果需要做某些事情,节点总是会做点什么。
与其他框架一样,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
}