1. 首先,JavaScript是单线程
JavaScript这一语言最大的特性就是单线程,所谓单线程,也就是同一时间只能做一件事。可是JavaScript为什么不采用多线程呢?这样可以提高效率呀。
其实JavaScript的单线程是和它本身的用途有关的。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,以防止一些复杂的同步问题的发生。比如,JavaScript有两个线程,一个线程是在某个DOM节点上添加内容,另一个线程是删除这个节点。那这时浏览器要以哪个线程为准呢?
所以,为了避免复杂性,JavaScript从一诞生,它就是单线程,这已经是它最核心的特征,将来也不会改变。
而为了利用多核CPU的计算能力,HTML 5提出了Web Worker标准,允许JavaScript脚本创建出多个线程,但是子线程完全受主线程控制,且不得操作DOM。其实,这个新标准并未改变JavaScript单线程的本质特性。
2. 任务队列
单线程就意味着,前一个任务完成,后一个任务才能开始。如果前一个任务耗时很长,那么后一个任务就只能等着。
如果排队是因为计算量太大,CPU忙不过来,那也能理解,但是很多时候CPU是闲着的,原因在于I/O设备很慢,不得不等结果出来,才能继续下一个任务。
JavaScript的设计者意识到,这时主线程可以不必管I/O设备,可以先将这些通过I/O设备才能完成的任务挂起来,先执行排在其后的那些任务。等到I/O设备返回了结果,再回过头,把这些挂起的任务执行下去。
Node.js最初开始于2009年,是一个可以让Javascript代码离开浏览器的执行环境也可以执行的项目。
Node.js将事件驱动的I/O模型与适合该模型的编程语言(Javascript)融合在了一起。
1. Node.js,它很快
Node.js是JavaScript的运行环境,使用了Google用在Chrome的V8引擎。V8以闪电一般的速度编译执行JavaScript,是因为V8将JavaScript编译成本地的机器代码。
2. Node.js的Event Loop机制
Node.js也是单线程的Event Loop,但是它的运行机制不同于浏览器环境。
下图作者(作者@BusyRich)
Node.js的运行机制如下:
- V8引擎解析JavaScript脚本
- 解析后的代码,调用Node API
- Libuv库负责Node API 的执行。它将不同的任务分配给不同的线程,形成一个Event Loop,以异步的方式将任务的执行结果返回给V8引擎
- V8引擎再将结果返回给用户