什么是 Event Loop?

Event Loop 是一个很重要的概念,指的是计算机系统的一种运行机制。

JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。

本文参考C. Aaron Cois的《Understanding The Node.js Event Loop》,解释什么是Event Loop,以及它与JavaScript语言的单线程模型有何关系。

想要理解Event Loop,就要从程序的运行模式讲起。运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。

如果有很多任务需要执行,不外乎三种解决方法。

(1)排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。 (2)新建进程。使用fork命令,为每个任务新建一个进程。 (3)新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。(进程和线程的详细解释,请看这里。)

以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即采用上面的第一种方法。一旦遇到大量任务或者遇到一个耗时的任务,网页就会出现"假死",因为JavaScript停不下来,也就无法响应用户的行为。

你也许会问,JavaScript为什么是单线程,难道不能实现为多线程吗?

这跟历史有关系。JavaScript从诞生起就是单线程。原因大概是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。后来就约定俗成,JavaScript为一种单线程语言。(Worker API可以实现多线程,但是JavaScript本身始终是单线程的。)

如果某个任务很耗时,比如涉及很多I/O(输入/输出)操作,那么线程的运行大概是下面的样子。

上图的绿色部分是程序的运行时间,红色部分是等待时间。可以看到,由于I/O操作很慢,所以这个线程的大部分运行时间都在空等I/O操作的返回结果。这种运行方式称为"同步模式"(synchronous I/O)或"堵塞模式"(blocking I/O)。

如果采用多线程,同时运行多个任务,那很可能就是下面这样。

上图表明,多线程不仅占用多倍的系统资源,也闲置多倍的资源,这显然不合理。

Event Loop就是为了解决这个问题而提出的。Wikipedia这样定义:

"Event Loop是一个程序结构,用于等待和发送消息和事件。(a programming construct that waits for and dispatches events or messages in a program.)"

简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为"主线程";另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为"消息线程")。

上图主线程的绿色部分,还是表示运行时间,而橙色部分表示空闲时间。每当遇到I/O的时候,主线程就让Event Loop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,Event Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。

可以看到,由于多出了橙色的空闲时间,所以主线程得以运行更多的任务,这就提高了效率。这种运行方式称为"异步模式"(asynchronous I/O)或"非堵塞模式"(non-blocking mode)。

这正是JavaScript语言的运行方式。单线程模型虽然对JavaScript构成了很大的限制,但也因此使它具备了其他语言不具备的优势。如果部署得好,JavaScript程序是不会出现堵塞的,这就是为什么node.js平台可以用很少的资源,应付大流量访问的原因。

(完)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • window.opener.location 安全风险讨论

    在浏览器中,通过 <a> 标签或者 JavaScript 中的 window.open 函数,可以打开新页面。新页面的 window 对象中,存在一个 open...

    逸鹏
  • 评论JS插件~多说+畅言

    多说API:http://dev.duoshuo.com/docs/512d6e2e418847315a000001 发表评论 接口名称 /posts/crea...

    逸鹏
  • 四款JavaScript库,助您搞定数据分析与可视化

    无论来自哪个行业,世界各地的企业都开始越来越多地意识到数据驱动型决策的重要意义。数据分析目前已经成为各行各业最为关注的议题之一,企业亦开始专注于从数据中获取有...

    灯塔大数据
  • JavaScript加密逻辑分析与Python模拟执行实现数据爬取

    本节来说明一下 JavaScript 加密逻辑分析并利用 Python 模拟执行 JavaScript 实现数据爬取的过程。在这里以中国空气质量在线监测分析平台...

    崔庆才
  • 使用ABAP和JavaScript代码生成PDF文件的几种方式

    详细步骤参考我的博客Convert word document into PDF via Adobe Livecycle Enterprise service

    Jerry Wang
  • 使用ztree.js,受益一生,十分钟学会使用tree树形结构插件

    看到ztree.js,这几个字眼,毋庸置疑,那肯定就是tree树形结构了,曾经的swing年代有jtree,后来jquery年代有jstree和treeview...

    风间影月
  • 基于HTML的PDF展示 pdf.js

    很不错的一个插件,推荐给大家 pdf.js 是一个技术原型主要用于在 HTML5 平台上展示 PDF 文档,无需任何本地技术支持。 ? 在线演示:http://...

    逸鹏
  • HTML/CSS/JavaScript学习笔记【持续更新】

    HTML <font> 标签 定义和用法 <font> 规定文本的字体、字体尺寸、字体颜色。 实例 规定文本字体、大小和颜色: 1 <font size="3"...

    Angel_Kitty
  • 省市区 - 三级联动通用化模块组件

    都说我们要做模块化设计,而不要做功能化设计 什么是模块化设计,就是可插拔性高,组件化,想要就用,不要用拉倒,直接删除就行 什么是功能化设计,就是一个简单的功能,...

    风间影月
  • Javascript调试命令——你只会Console.log() ?

    Console 对象提供对浏览器控制台的接入(如:Firefox 的 Web Console)。不同浏览器上它的工作方式是不一样的,但这里会介绍一些大都会提供的...

    崔庆才

扫码关注云+社区

领取腾讯云代金券