Node.JS中事件轮询(Event Loop)的解析


Posted in Javascript onFebruary 25, 2017

当我们知道I/O操作和创建新线程的开销是巨大的!

网站延迟的开销

对于一个网站,后台大多不需要进行复杂的计算,我们的程序大多时间花费在I/O读取上。

看到一个数据:IO操作可以比数据处理慢几个数量级。高端SSD固态硬盘的读取速度可以达到200mb-700mb/s;读取1000字节需要1.4微秒。而在此期间,2GHZ频率的CPU可以执行28000个指令处理周期。而网络数据的IO甚至更慢!

Node.JS中事件轮询(Event Loop)的解析

NodeJS采用单线程非阻塞的架构解决老大难的IO问题

当采用多线程时,为每一个请求开启一个新的线程(Apache就是这样做的)。当并发增多,线程的消耗会十分严重。

什么是阻塞和非阻塞呢?

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

var fs = require("fs");
fs.readFile("./testfile", "utf8", function(error, file) { 
  if (error) throw error; 
  console.log("我读完文件了!");
});
console.log("我不会被阻塞!");

用node执行以下代码,会先输出我不会被阻塞,再输出我读完文件了

一个知乎的回答:

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

NodeJS的事件轮询

这是node虽然为单线程,但是可以处理大并发,高吞吐量的核心。一个事件轮询拥有下面三个组件

  1. 事件队列:这是一个FIFO模型的队列,一方推入事件,另一方推出事件
  2. 队列的读取轮询线程组件,也就是主角Event Loop,
  3. 单独的线程池,用来执行长任务(也就是threadpool,node底层,用C++写的,不会阻塞)

Node.JS中事件轮询(Event Loop)的解析

在nodejs中,只有一个主线程(也就是前面说的单线程)来不断读取轮询(书中称为调用I/O观察者)队列中是否有事件。

而对于读取文件,HTTP

请求等(现代cpu处理能力很强,事件处理相当快,导致运行速度下降的瓶颈在I/O)比较容易堵塞的事件,就在这个单线程中

执行肯定会造成堵塞,所以Event Loop

会把这类型的事件交给底层的线程池执行,并给予线程池一个回调函数,当线程池操作

完成这堵塞任务后,便把结果和回调函数一起再放入轮询队列中。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
js 鼠标点击事件及其它捕获
Jun 04 Javascript
jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭)
Apr 01 Javascript
JavaScript 打地鼠游戏代码说明
Oct 12 Javascript
国外大牛IE版本检测!现在IE都到9了,IE检测代码
Jan 04 Javascript
ie中js创建checkbox默认选中问题探讨
Oct 21 Javascript
jquery放大镜效果超漂亮噢
Nov 15 Javascript
jquery实现浮动在网页右下角的彩票开奖公告窗口代码
Sep 04 Javascript
3种不同的ContextMenu右键菜单实现代码
Nov 03 Javascript
vue router下的html5 history在iis服务器上的设置方法
Oct 18 Javascript
浅析微信扫码登录原理(小结)
Oct 29 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
Nov 11 Javascript
详解Vue中$props、$attrs和$listeners的使用方法
Feb 18 Vue.js
走进javascript——不起眼的基础,值和分号
Feb 24 #Javascript
angular.js 路由及页面传参示例
Feb 24 #Javascript
实例解析js中try、catch、finally的执行规则
Feb 24 #Javascript
js中开关变量使用实例
Feb 24 #Javascript
angularjs点击图片放大实现上传图片预览
Feb 24 #Javascript
js实现导航吸顶效果
Feb 24 #Javascript
canvas绘制多边形
Feb 24 #Javascript
You might like
跟我学Laravel之路由
2014/10/15 PHP
PHP读取大文件的几种方法介绍
2016/10/27 PHP
php的socket编程详解
2016/11/20 PHP
PHP使用redis消息队列发布微博的方法示例
2017/06/22 PHP
PHP const定义常量及global定义全局常量实例解析
2020/05/28 PHP
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
避免回车键导致的页面无意义刷新的解决方法
2011/04/12 Javascript
JS高级拖动技术 setCapture,releaseCapture
2011/07/31 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
2013/12/19 Javascript
javascript中的取反再取反~~没有意义
2014/04/06 Javascript
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
Js删除数组中某一项或几项的几种方法(推荐)
2016/07/27 Javascript
JavaScript异步上传图片文件的实例代码
2017/07/04 Javascript
bootstrap confirmation按钮提示组件使用详解
2017/08/22 Javascript
node.js学习之事件模块Events的使用示例
2017/09/28 Javascript
vue 内置过滤器的使用总结(附加自定义过滤器)
2018/12/11 Javascript
详解wepy开发小程序踩过的坑(小结)
2019/05/22 Javascript
Jquery属性的获取/设置及样式添加/删除操作技巧分析
2019/12/23 jQuery
javascript中正则表达式语法详解
2020/08/07 Javascript
python查询sqlite数据表的方法
2015/05/08 Python
Python 数据结构之队列的实现
2017/01/22 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
python删除服务器文件代码示例
2018/02/09 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
简单了解Django ContentType内置组件
2019/07/23 Python
Python偏函数Partial function使用方法实例详解
2020/06/17 Python
CSS3的 fit-content实现水平居中
2017/09/07 HTML / CSS
html5实现多图片预览上传及点击可拖拽控件
2018/03/15 HTML / CSS
html5唤醒APP小记
2019/03/27 HTML / CSS
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
财会专业毕业生自荐信
2014/07/09 职场文书
党员民主评议自我评价
2014/10/20 职场文书
2015年女职工工作总结
2015/05/15 职场文书
妇联2016年六一国际儿童节活动总结
2016/04/06 职场文书
Java的Object类的九种方法
2022/04/13 Java/Android