文章目录
- nodeJS是什么?
- 优缺点
- 使用场景
- 全局对象
- 适合用于构建 I/O 密集型
- 不适用于计算密集型任务
nodeJS是什么?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它是跨平台和开源的。 Node.js 使用高效、轻量级的事件驱动、非阻塞 I/O 模型。它的包生态系统,npm,是目前世界上最大的开源库生态系统。
特点:
- 非阻塞异步I/O:在做I/O操作的时候不会造成任何的阻塞,当完成之后,以时间的形式通知执行操作
🌰:例如在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率 - 事件驱动:当进来一个新的请求的时,请求将会被压入一个事件队列中,然后通过一个循环来检测队列中的事件状态变化,如果检测到有状态变化的事件,那么就执行该事件对应的处理代码,一般都是回调函数
🌰:比如读取一个文件,文件读取完毕后,就会触发对应的状态,然后通过对应的回调函数来进行处理
和js的区别
优缺点
-
优点:
- 高性能:Node.js采用事件驱动、异步编程模型,能够处理大量并发请求,具有较高的性能。
- 跨平台:Node.js可以在多个操作系统上运行,包括Windows、Linux、Mac OS等。
- 生态系统丰富:Node.js拥有庞大的开源社区,提供了大量的模块和工具,方便开发人员快速构建应用程序。
- 易于学习:Node.js使用JavaScript语言,对于前端开发人员来说,学习成本较低。
-
缺点:
- 单线程:Node.js采用单线程模型,如果某个请求阻塞了线程,会影响整个应用程序的性能。
- 不适合CPU密集型任务:由于Node.js采用单线程模型,不适合处理CPU密集型任务,例如图像处理、视频编码等。
回调函数嵌套:由于Node.js采用异步编程模型,代码中会出现大量的回调函数嵌套,导致代码可读性较差。
使用场景
具体使用场景:
- 第一大类:用户表单收集系统、后台管理系统、实时交互系统、考试系统、联网软件、高并发量的web应用程序
- 第二大类:基于web、canvas等多人联网游戏
- 第三大类:基于web的多人实时聊天客户端、聊天室、图文直播
- 第四大类:单页面浏览器应用程序
- 第五大类:操作数据库、为前端和移动端提供基于json的API
全局对象
Nodejs中的全局对象是 global
- Class:Buffer
- process
- console
- clearInterval、setInterval
- clearTimeout、setTimeout
- global
适合用于构建 I/O 密集型
🌰:网络服务器、数据库系统和文件传输等
原因:从上面的分析中我们知道Node会将所有的I/O操作通过libuv的多线程能力分散到不同的线程里面执行,其余的操作都放在主线程里面执行。那么为什么这种做法就比Java或者Golang等其它语言更适合做I/O密集型应用呢?我们以开发Web服务为例,Java和Golang等主流后端编程语言的并发模型是基于线程(Thread-Based)的,这也就意味他们对于每一个网络请求都会创建一个单独的线程来处理。可是对于Web应用来说,主要还是对数据库的增删改查,或者请求其它外部服务等网络I/O操作,而这些操作最后都是交给操作系统的系统调用来处理的(无需应用线程参与),并且十分缓慢(相对于CPU时钟周期来说),因此被创建出来的线程大多数时间是无事可做的而且我们的服务还要承担额外的线程切换开销。和这些语言不一样的是Node没有为每个请求都创建一个线程,所有请求的处理都发生在主线程中,因此没有了线程切换的开销,并且它还会通过线程池的形式异步处理这些I/O操作,然后通过事件的形式告诉主线程结果从而避免阻塞主线程的执行,因此它理论上是更高效的。这里值得注意的是我只是说Node理论上是更快的,实际上真不一定。这是因为现实中一个服务的性能会受到很多方面的影响,我们这里只是考虑了并发模型这一个因素,而其它因素例如运行时消耗也会影响到服务的性能,举个例子,JavaScript是动态语言,数据的类型需要在运行时进行推断,而Golang和Java都是静态语言它们的数据类型在编译时就可以确定,所以它们实际执行起来可能会更快,占用内存也会更少。
不适用于计算密集型任务
🌰:数据处理、图像处理、加密解密
NodeJS 的非阻塞机制使其即使仅能使用单个线程但仍能应对高并发量的场景,但也正是因为其仅能使用单个线程,无法充分利用多核 CPU 的带来的性能优势,所以其不适用于 计算密集型 的 WEB 应用程序。
原因:上面我们提到Node除了I/O相关的操作其余操作都会在主线程里面执行,所以当Node要处理一些CPU密集型的任务时,主线程会被阻塞住。
Node这种基于事件循环的单线程执行环境才会有这种问题,Java和Golang等Thread-Based语言是不会存在这种问题的。
解决方案:Cluster Module,Child Process和Worker Thread