Node.js简介

目录

  • Node.js
    • Node.js简介
    • Node.js的引用场景
      • 1.前端工程化
      • 2.Web服务端应用
      • 3.Electron 跨端桌面应用
    • Node.js 运行时结构
    • Node.js特点
      • 1.异步I/O
      • 2.单线程
      • 3.跨平台

Node.js

Node.js简介

  • Node.js是一个能够在服务器端运行JavaScript的开源代码、跨平台JavaScript运行环境。
  • Node是Ryan Dahl为了帮助客户解决Web服务器的高并发性能问题而写出来的。
  • Node采用Google开发的V8引擎运行js代码,使用事件驱动非阻塞异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模。
  • Node.js的推出不仅从工程化的角度自动化掉更多繁琐费时的工作,更打破了前端后端的语言边界。
    注释:I/O(Input/Output) I/O操作指的是对磁盘读写操作

Node.js的引用场景

1.前端工程化

Node.js简介_第1张图片

再早期ajax,jQuery比较流行的时候,使用这些库我们在页面中直接引入需要的库(lib)即可,不太需要那么多服务端的能力。后续随着模块化、transpile逐渐成熟、需求逐渐增多,对后端能力的需求也逐渐强烈。反过来说,也是Node.js赋予了js开发者在浏览器外运行代码的能力了,加速催生了这些项目的出现。

  • Bundle(打包工具):Webpackvite、esbuild、parcel
  • Uglify(代码压缩):uglifyjs
  • Transpile(语法转换):bablejs、TypeScript
  • 其他语言加入前端工程化的竞争:esbuild、parcel、prisma
  • Node.js仍然处于难以替代的地位

2.Web服务端应用

Node.js简介_第2张图片

  • 学习曲线平缓,开发效率极高
  • 运行效率接近常见的编译语言
  • 社区生态丰富及工具链成熟(NPM, V8 inspector)
  • 与前端结合的常见会有优势(SSR(服务端渲染))
  • 现状:竞争激烈,但是Node.js有自己独特的优势

3.Electron 跨端桌面应用

Node.js简介_第3张图片

  • 商业应用:VsCode,slack, discord,zoom
  • 大型公司内部的效率工具
  • 现状:大部分场景在选型时,都值得考虑使用Node.js

Node.js 运行时结构

Node.js简介_第4张图片

  • 社区npm代码acron,node-inspect(诊断调试工具),npm
  • 用户代码:自己写的业务代码,还包括npm安装的包
  • Node.js Core(JavaScript): 内部由JavaScript代码写的模块
  • Node.js Core(C++):Node底层有更多是由C++代码去编写的
  • N-API:是在一些特定的场景,通过JavaScript代码没法满足的需求,举个例子当你有一些需要性能的需求,比如某个场景用JavaScript写的代码效率比较低,所以就需要一些N-API的一系列模块来实现这些能力
  • V8:JavaScript Runtime,由V8自带的工具inspector(诊断调试工具)
  • libuv:封装了各类操作系统的API,还提供了Node.js最核心的eventloop(事件循环)syscall(系统调用) ,它会去封装各类操作系统上的API,然后来提供一个跨平台I/O操作
  • nghttp2:提供了http2相关的模块
  • zlib:常见的压缩和解压缩的算法
  • c-ares:做的dns查询的库
  • llhttp: 做http协议的解析(序列化或反序列化)
  • OpenSSL:常用在网络层面上的加密和解密的工具

例子: 用node-fatch发起请求时,大概调用顺序

  • 首先通过npm去安装node-fatch模块就到达用户代码
  • 然后再用户代码里面调用node-fatch模块,因为这些代码都是JavaScript代码,所以它会到底层V8里面去执行
  • 然后v8会调用Node.js Core(JavaScript) 里面的http模块
  • 然后http模块调用更底层的Node.js Core(C++) 的API
  • 然后到llhttp去做http协议的序列化和反序列化,把得到的数据通过libuv
  • libuv可能会创建一个TCP/IP链接,再把这个数据发送给远端
  • 反之接收即流程反过来走一次,从libuv用户代码就完成了接收

Node.js特点

1.异步I/O

当Node.js执行I/O操作时,会在响应返回后回复操作,而不是阻塞线程并占用额外内存等待
常见异步处理

setTimeout(()=>{
    console.log("B");
})
console.log("A");

先打印A,后打印B
下面是异步读取文件场景
Node.js简介_第5张图片
在调用异步API读取文件的时候,就会触发一个异步调用,然后就会将这个读取文件的操作交给libuv的线程池去做,主线程就不需要等待文件读取完成,就可以先去做其他调用,等线程池的读取文件操作结束返回数据给主线程就行了

2.单线程

这里主要是指Node.js的JavaScript的线程是单线程的,所以Node.js不适合做一些cpu密集的操作,例如下面这种例子,但是从版本12开始,就可以使用worker_thread模块单独起独立JavaScript线程,但每个线程的模型和主线程没有太大的变化,使用上也不会有太大的区别

function fibonacci(num){
    if(num === 1 || num === 2){
        return 1;
    }
    return fibonacci(num - 1) + fibonacci(num - 2);
}

fibonacci(42);
fibonacci(43);

JS单线程: 一般说Node.js是单线程是指JavaScript线程为单线程

  • 实际上Node还有其他线程:JS线程 + libuv线程池(4个线程) + V8任务线程池 + V8 Inspector线程;
    • libuv线程池: Node.js为了不阻塞一些操作,就会把一些操作(例如:异步读取文件)交给libuv线程池里面的线程执行,还包括一些对cpu消耗时间比较大的操作(例如加密解密)也会交给libuv线程池去操作
    • V8任务线程池:调整V8本身的线程池,大部分不会单独去调整这个
    • V8 Inspector线程: 当V8做调试的时候,会使用这个线程,当做调试的时候,比如在代码中写了个死循环,只有这类调试工具在单独的线程上,这样才能调试死循环的问题
      优点
  • 不用考虑多线程状态同步问题,也就不需要锁
  • 同时还能比较高效的利用系统资源
    缺点:
  • 如果出现阻塞问题会产生更多的负面影响
  • 解决办法:多进程或多线程

3.跨平台

例如我想使用Linux系统上面的socket,在windows上使用同样的代码也是做类似的事情,在跨平台方面上,使用Node.js的时候,它已经完成了绝大部分的工作,就不用考虑太大跨平台的问题

const net = require('net');

const socket = new net.Socket('./tmp/scoket.sock')
  • 大部分功能、API是跨平台的
  • Node.js跨平台 + JS无需编译环境( + Web 跨平台 + 诊断工具跨平台 ) = 开发成本低(大部分场景无需担心跨平台问题),整体学习成本低

你可能感兴趣的:(正在路上的前端攻城狮的烂笔记,#,Node.js,#,JavaScript,node.js,前端,javascript)