Nodejs 架构
Natives modules(内置核心模块)
- 当前层内容由js实现,暴露了响应的js功能接口
- 提供应用程序可以直接调用的库,例如fs、path、http等
- js语言无法直接操作底层硬件设备
Builtin modules(v8配合执行)
- 桥梁层 由C++代码编写完成的
底层
- v8: 执行js代码,提供桥梁接口,
- 提供了初始化动作,创建了执行上下文环境,和作用域
- Libuv库: 事件循环、事件队列、异步IO
- 第三方模块: zlib、http、c-ares等
为什么是nodejs
Reactor
- Reactor模式,单线程完成多线程工作
- Reactor模式下实现异步IO、事件驱动、单线程
nodejs更适用与IO密集型高并发请求
特点
异步IO、事件驱动、单线程、事件循环
nodejs异步IO
阻塞IO和非阻塞IO
node中具体执行异步IO的过程
执行Node代码 -> 如果是异步代码,那么会通过event loop 进行处理,类似于js的事件循环 当遇到IO时,转交IO处理给 事件多路分解器(event demultiplexer)->调用操作系统层面的IO接口,然后最终返回结果 -> 通过事件队列event (Enqueue Event)把返回结果对应的处理函数加入到事件队列中
IO分为网络IO和文件IO
- 网络IO会调用系统底层的IO
- 文件IO会放到node自行实现的线程池中处理
异步IO总结
- IO是应用程序的瓶颈所在
- 异步IO提高性能无需原地等待结果返回
- IO操作属于操作系统级别,平台都有对应实现
- Nodejs 单线程配合事件驱动架构及libuv实现了异步IO
Nodejs事件驱动架构
事件驱动架构是软件开发中的通用模式
事件驱动、发布订阅模式、观察者模式的对比
共通点
发布者发布消息,其他实例负责接收一开始订阅的消息
Nodejs单线程
- nodejs虽然是单线程的机制,但是配合异步io和事件循环可以实现高并发的请求
- nodejs的单线程指的是运行的js代码的主线程是单线程的,v8中用来执行js代码的部分是单线程的,但是在libuv库中存在存放多个线程的线程池的
- 不适合处理cpu密集型之类的任务的
Nodejs 实现API服务
使用node命令执行ts文件的时候 容易报错
- 这个时候需要安装一个
ts-node
模块配合去启动ts文件 - 同时使用
npx ts-node api_server.ts
去使用ts-node
命令 - 直接使用
ts-node
会报命令不存在的错,这是由于npm是不能直接使用node_modules/.bin
文件中的ts-node
启动脚本的
nodejs全局对象
- 与浏览器平台的window不完全相同
- Nodejs 全局对象上挂载着许多属性
全局对象是JavaScript中的特殊对象,nodejs中全局对象是global
- Global的根本作用就是作为全局变量的宿主
- 全局对象可以看作是全局变量的宿主
nodejs常见全局变量
__filename
: 返回正在执行脚本文件的绝对路径__dirname
: 返回正在执行脚本所在目录- timer类函数: 执行顺序与实践循环之间的关系(settimeout等)
process
: 提供与当前进程互动接口require
: 实现模块的加载module/export
: 处理模块的导出
node环境中,默认情况下 this 是一个空对象,和global 并不是一样的
- 上面的状况,这跟当前node环境模块化的实现是有关系的,
- 在node环境下每一个js文件都是一个独立的模块,模块与模块之间是互相独立的,可以理解为当前js文件的所有内容在执行的时候,在最外层都包了一层自调用函数
全局变量-- process
- 获取进程信息,执行进程操作
// console.log(global)
// console.log(__filename)
// console.log(__dirname)
// console.log(this) // {}
// 默认情况下 this 是一个空对象,和global 并不是一样的
// console.log(this === global); // false
// (function () {
// console.log(this === global) // true
// })()
// 1 资源: cpu 内存
// console.log(process.memoryUsage())
// console.log(process.cpuUsage())
// 2 运行环境: 运行目录、node环境、cpu架构、用户环境、系统平台
// console.log(process.cwd())
// console.log(process.version)
// console.log(process.versions)
// console.log(process.arch)
// console.log(process.env.NODE_ENV)
// console.log(process.env.PATH)
// console.log(process.env.HOME) // USERPROFILE 管理员目录
// console.log(process.platform)
// 3 运行状态:启动参数、PID、运行时间
// console.log(process.argv)
// console.log(process.argv0)
// // console.log(process.execArgv)
// console.log(process.pid) //ppid
// setTimeout(() => {
// console.log(process.uptime())
// }, 2000);
// 4 事件
// process.on('exit', code =>{
// console.log('exit',code)
// // 这里只能执行同步代码
// })
// process.on('beforeExit', code =>{
// console.log('before exit',code)
// // setTimeout(() => {
// // console.log('settimeout')
// // }, 1000);
// })
// console.log('代码执行完了')
// process.exit()
//5 标准输出 输入 错误
// console.log = function (data) {
// process.stdout.write('----'+ data+'\n')
// }
// console.log(11)
// console.log(22)
// const fs = require('fs')
// fs.createReadStream('test.txt')
// .pipe(process.stdout)
// process.stdin.pipe(process.stdout)
// process.stdin.setEncoding('utf-8')
// process.stdin.on('readable',()=>{
// let chunk = process.stdin.read()
// if(chunk){
// process.stdout.write('data'+ chunk)
// }
// })