摘要:实际上官方给出的单线程是具有误导性的。如果开发者在回调函数中调用了阻塞方法比如上文中的函数,那么整个事件轮询就会阻塞,事件队列中的事件得不到及时处理。后记参考文章事件轮询详述
前言
总括 :
原文地址:理解Node.js的事件轮询
Node小应用:Node-sample
智者阅读群书,亦阅历人生
正文 Node.js的两个基本概念Node.js的第一个基本概念就是I/O操作开销是巨大的:
所以,当前变成技术中最大的浪费来自于等待I/O操作的完成。有几种方法可以解决性能的影响:
同步方式:按次序一个一个的处理请求。利:简单;弊:任何一个请求都可以阻塞其他所有请求。
开启新进程:每个请求都开启一个新进程。利:简单;弊:大量的链接意味着大量的进程。
开启新线程:每个请求都开启一个新线程。利:简单,而且跟进程比,对系统内核更加友好,因为线程比进程轻的多;弊:不是所有的机器都支持线程,而且对于要处理共享资源的情况,多线程编程会很快变得太过于复杂。
第二个基本概念是每个连接都创建一个新线程是很消耗内存的(例如:你可以对比Nginx回想一下Apache内存耗尽的情景)。
Apache是多线程的:它为每个请求开启一个新的线程(或者是进程,这取决于你的配置),当并发连接增多时,你可以看看它是怎么一点一点耗尽内存的。Nginx和Node.js不是多线程的,因为线程的消耗太“重”了。它们两个是单线程、基于事件的,这就把处理众多连接所产生的线程/进程消耗给消除了。
单线程确实只有一个线程:你不能并行执行任何代码,比如:下面的“sleep”将会阻塞sever1秒钟:
function sleep() { var now = new Data().getTime(); while (new Date().getTime() < now + 1000) { // do nothing } } sleep();
但就我目前学习阶段而言,我觉得好多人对于所谓的node单线程是有误解的。实际上官方给出的“单线程”是具有误导性的。所谓的单线程是指你的代码只运行在一个线程上(好多地方都叫它主线程,实际上Javascript的浏览器运行环境不也是这么处理我们写的Javascript代码的嘛),而诸多任务的并行处理,就需要多线程了,如下图:
如上图,Node.js中的单线程之说指的就是这个主线程,这个主线程有一个循环结构,保持着整个程序(你写的代码)的运转。
事件轮询其实上面我们所说的维持主线程运行的循环这部分就是"事件轮询",它存在于主线程中,负责不停地调用开发者编写的代码。但对开发者是不可见的。so...开发者编写的代码是怎样被调用的呢?看下图:
如上图,异步函数在执行结束后,会在事件队列中添加一个事件(遵循先进先出原则),主线程中的代码执行完毕后(即一次循环结束),下一次循环开始就在事件队列中"读取"事件,然后调用它所对应的回调函数(所以回调函数的执行顺序是不一定的)。如果开发者在回调函数中调用了阻塞方法(比如上文中的sleep函数),那么整个事件轮询就会阻塞,事件队列中的事件得不到及时处理。正因为这样,nodejs中的一些库方法均是异步的,也提倡用户调用异步方法。
var fs = require("fs"); fs.readFile("hello.txt", function (err, data) { //异步读取文件 console.log("read file end"); }); while(1) { console.log("call readFile over"); }
如上代码,我们虽然使用了异步方法readfile读取文件,但read file end永远不会输出,因为代码始终在while循环中,下一次事件轮询始终没法开始,也就没法"读取"事件队列调用相应的回调函数了。
最后有一个Node-sample是博主平时积累的一些代码,包含注释,汇总成了一个小应用,还是可以看到学习的蛛丝马迹的。感兴趣的您可以看看。
后记参考文章:
Understanding the node.js event loop
nodejs事件轮询详述
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86777.html
摘要:定时器阶段这个是事件循环开始的阶段,绑定到这个阶段的队列,保留着定时器的回调,尽管它并没有将回调推入队列中,但是以最小的堆来维持计时器并且在到达规定的事件后执行回调。 本文,将会详细的讲解 node.js 事件循环工作流程和生命周期 一些常见的误解 在 js 引擎内部的事件循环 最常见的误解之一,事件循环是 Javascript 引擎(V8,spiderMonkey等)的一部分。事实上...
摘要:检索新的事件执行与相关的回调几乎所有,除了由定时器调度的一些和将在适当的时候在这里阻塞。在事件循环的每次运行之间,检查它是否在等待任何异步或定时器,如果没有,则彻底关闭。 Node.js事件循环、定时器和process.nextTick() 什么是事件循环? 事件循环允许Node.js执行非阻塞I/O操作 — 尽管JavaScript是单线程的 — 通过尽可能将操作卸载到系统内核。 ...
摘要:回调函数执行几乎所有的回调函数,除了关闭回调函数,定时器计划的回调函数和。轮询此阶段有两个主要的功能执行已过时的定时器脚本处理轮询队列中的事件。一旦轮询队列为空,事件循环将检查已达到时间阈值的定时器。 什么是事件循环(Event Loop)? 事件环使得Node.js可以执行非阻塞I/O 操作,只要有可能就将操作卸载到系统内核,尽管JavaScript是单线程的。 由于大多数现代(终端...
摘要:的单线程,与它的用途有关。特点的显著特点异步机制事件驱动。队列的读取轮询线程,事件的消费者,的主角。它将不同的任务分配给不同的线程,形成一个事件循环,以异步的方式将任务的执行结果返回给引擎。 这两天跟同事同事讨论遇到的一个问题,js中的event loop,引出了chrome与node中运行具有setTimeout和Promise的程序时候执行结果不一样的问题,从而引出了Nodejs的...
摘要:如果当前没有事件也没有定时器事件,则返回。相关资料关于的架构及设计思路的事件讨论了使用线程池异步运行代码。下一篇初窥事件机制的实现二中定时器的实现 在浏览器中,事件作为一个极为重要的机制,给予JavaScript响应用户操作与DOM变化的能力;在Node.js中,事件驱动模型则是其高并发能力的基础。 学习JavaScript也需要了解它的运行平台,为了更好的理解JavaScript的事...
阅读 2249·2021-11-15 11:37
阅读 2905·2021-09-01 10:41
阅读 730·2019-12-27 11:58
阅读 717·2019-08-30 15:54
阅读 689·2019-08-30 13:52
阅读 2895·2019-08-29 12:22
阅读 1042·2019-08-28 18:27
阅读 1418·2019-08-26 18:42