当前位置: 首页 > 后端技术 > Node.js

关于node.js的一些简单认识

时间:2023-04-04 00:32:03 Node.js

1.对Node.js的整体认知Node.js是一个JavaScript的服务端运行环境。它使JS能够像PHP、Python等语言一样开发服务器端程序。淘汰了传统JS中的DOM和BOM。首先,它遵循EMCAScript标准来实现核心JavaScript。在此基础上实现了模块、包、文件系统、网络通信、操作系统API等新功能。Node内部使用GoogleChrome的V8引擎作为JavaScript语言的解释器,在引擎中执行ES代码。此外,Node平台还提供了一些组件,用于通过自研的Libuv库对操作系统资源进行调度。2.Node.js在Web中的作用1.做一个动态网站2.分发数据请求和渲染HTML页面3.Node.js的核心特性(事件驱动和非阻塞)首先我们来了解一下概念进程和线程。进程:操作系统为应用程序分配资源的单位。用于为应用程序提供运行环境。线程:用于执行应用程序中的代码,一个进程内部可以有多个线程。但是在一个线程内部,同一时间只能做一件事。应用程序启动后,默认会创建一个主线程来执行我们的代码。但是,用户的代码中通常会有耗时的阻塞代码。对于Java等应用程序,.执行阻塞在主线程中的代码。多线程的问题:创建线程会消耗资源,线程数量有限。有些数据是线程间共享的,同步某个状态比较麻烦。CPU在不同线程之间切换是非常耗时的。但是对于Node来说,由于Node使用了ChromeV8引擎HandleJavaScript脚本,而V8最大的特点就是单线程运行。即Node内部只允许有一个线程,所以为了提高代码的执行效率,避免代码阻塞的发生。Node使用了很多异步操作。即Node中所有导致代码阻塞的操作都是异步的。3.1.Node中的事件驱动模型在Node内部有一个事件队列。事件队列由一对一的键值对组成,即events:对应回调函数的形式。在执行用户代码的过程中,Node的主线程首先执行那些非阻塞代码。当它执行文件操作或网络操作等阻塞代码时,它会根据它们的任务代码出现的顺序来释放它们。进入事件队列,任务相关的代码放在任务的回调函数中。即Node主线程在程序执行过程中会直接执行那些非阻塞代码,但是如果在执行过程中遇到阻塞代码,那么主线程的处理只是处理事件函数及其对应的回调function放入事件队列,暂时不执行。主线程执行完程序中的所有非阻塞代码后,会从事件队列中从上到下依次取出事件任务执行。Node在执行事件队列中的任务时,首先执行阻塞事件,然后开始执行该事件对应的回调函数。在回调函数执行过程中,也是先执行非阻塞代码。对于callbacks函数中的阻塞事件也暂时不执行时,将该事件及其对应的回调函数插入到事件队列的尾部。3.2.Node内部的线程池模型Node有一个事件循环(EventLoop),从事件队列(EventQueue)中依次执行事件。对于事件队列的键值对,阻塞事件从头开始执行,在开始执行事件对应的回调函数的过程中,可能会设计文件或网络操作,可能会阻塞很长时间,但实际上代码不会卡在这里。因为这里的阻塞操作并不是由节点主线程来完成的,而是交给了另外一个线程来完成。节点底层维护了一个线程池,线程池内部维护了很多线程。当EventLoop依次执行事件队列中的事件时,如果遇到阻塞操作,就会交给线程池中的线程处理。这对主线程没有影响,主线程仍然继续沿着EventLoop往下走,然后处理事件队列中的下一个事件。不必等待事件队列中上一个事件的回调函数完成后,再执行下一个事件。当线程池中的线程执行完分配给它的任务后,会通知EventLoop中的主线程执行相应的回调函数。然后线程被释放并返回到线程池。Node其实内部是多线程的。对于文件操作等阻塞操作,让另一个线程来度过这段时间,而主线程一直在马不停蹄地工作。一般我们说node是单线程的,因为对于对外的API来说,所有的任务都是一个线程完成的,只有一些内部的阻塞操作交给内部的线程池来完成。Node将所有阻塞操作交给内部实现的线程池,而Node主线程自己负责不间断的往返调度。非阻塞最大的性能优势是可以充分利用单核CPU的优势。如果单核CPU不断在多个线程之间切换,会造成很大的性能损耗。Node采用事件驱动的异步I/O模型,大大提高了HTTP服务器的并发性能。