Node.js学习|青训营笔记

91 阅读4分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 7 天,欢迎各位大佬批评指正。

Node 概述

Node.js 应用场景

node.js是基于V8引擎的ECMAScript运行时环境,可以执行js文件,并且提供大量API,使得能快速完成文件读写,web服务器创建等,大大拓展了js的应用领域(可以像javapython一样完成一些后端/服务端的能力)。具体的应用可以细分如下:

  1. 前端工程化

前端工程化越来越成为目前前端标准化开发的主流模式,比如:

  • Budler:webpackviteesbuildparcel...
  • Transpile:babeljstypescript...
  • Uglify:uglifyjs
  • 其他语言加入:esbuild (go)parcel (rust)prisma (新一代ORM)...
  1. Web服务端应用
  • 学习曲线平缓,运行效率接近常见的编程语言。
  • 社区生态丰富,工具链成熟(npm、V8 inspector等)。
  • 与前端结合的场景有较大优势(SSR等)。
  1. Electron跨端桌面应用
  • 依赖Electron开发的商业应用:vscodeslackdiscordzoom...
  • 大型公司内的效率工具...

💡node.js的出现不仅使得js不仅仅运行在浏览器环境,也可以运行在桌面、服务器等,极大拓展了js语言的活力,npm上过百万的包也展示了这项工具的生命力;前端的开发者摆脱了过去只能调用后端接口的尴尬局面,通过node.js可以简单写出一个web服务器应用,也可以通过工程化工具等,轻松实现跨端,前端开发的范围也越来越广~

Node.js 运行时结构

截屏2023-02-09 20.33.38.png

  1. 异步I/O

    I/OInput/Output,当处理器访问内存、磁盘、显卡等外部设备时,都可以当作I/O操作。Node.js作为单线程的模式,任务是顺序执行的,一旦有任务执行时间过长,会影响后续任务的执行。为了解决这个问题,Node.js采用了异步I/O模式,更合理得利用资源,提高程序运行效率。

  2. 事件循环机制

    对于异步I/O解决方式,就不得不提到Node.js中事件循环。和浏览器的事件循环有些许不同,不再分为宏任务、微任务,而是在由以下步骤组成:

截屏2023-02-09 21.32.02.png

  • timers:这个阶段执行setTimeoutsetInterval指定的回调函数。
  • I/O:此阶段执行上一次未完的系统的回调函数(即除了timers和close callback的全部回调)。
  • idle, prepare:空转,仅在node内部调用。
  • poll:轮询。首先同步执行队列中到期的I/O回调函数,执行结束判断是否有timers或setImmediate回调到期,无则I/O阻塞等待,有则跳转执行。
  • check:这个阶段用于执行setImmediate指定的回调。

如果poll队列任务执行结束后,如果有设置setImmediate,则会立即跳转check阶段,如果没有则阻塞等待,如果poll队列为空并且没有到期的setImmediate同时setTimeoutsetInterval到期,则立即跳转到timers执行。

Node.js 内置模块

文件模块

文件模块,即fs模块,是node中内置的一个模块,能够用于创建/删除文件,读写系统文件,获取文件详情等。通过require命令引入。

const fs = require('fs');

1. 读/写文件命令

  • 读取文件内容:path为文件路径;options可选,表示以何种编码模式解析文档;callback接受两个参数(err, datastr)
fs.readFile('path', ['options'], callback)
fs.readFileSync('path', ['options'])
  • 写入内容
fs.writeFile('path', datastr, ['options'], callback)
fs.writeFileSync('path', datastr, ['options'])
  • 追加文件内容
fs.appendFile('path', datastr, ['options'], callback)
fs.appendFileSync('path', datastr, ['options'])

2. 创建/删除/遍历文件

  • 查看文件状态
fs.stat('path', callback) //异步
fs.statSync('path') //同步
  • 判断是否为文件
fs.isFile('path')
  • 判断是否为目录
fs.isDirectory('path')
  • 删除文件
fs.unlink('path', callback)
fs.unlinkSync('path')
  • 创建目录
fs.mkdir('path', callback)
  • 读取目录
fs.readdir('path', callback)
  • 重命名
fs.rename('path', 'newname', callback)
  • 删除目录
fs.rmdir('path', callback)

注:后缀为Sync即同步操作,没有callback;否则为异步,一定有callback

路径模块

由于涉及到系统中文件读写,因此路径非常重要。node也提供了内置的模块帮助快速写出准确的路径:

const path = require('path');

//拼接路径
path.join('path1', 'path2', ...);

//获取路径最后的信息;如果加上后缀(第二个参数),只返回文件名
path.basename('path', ['suffix']);

//获取路径中扩展名部分
path.extname('path')

//当前执行文件所在目录
__dirname;

http 模块

内置模块,可用于快速搭建一个简单的web应用:

const http = require('http');
const sever = http.creatSever();

//给sever绑定请求事件响应
sever.on('request', (req, res) => {
    //业务代码
    console.log('request has been received');
    return true;
}

//启动服务器
sever.listen(port, callback)

Node.js 编写 http-sever

基于node有很多开源框架可以快速搭建一个较为完备的web框架,比如:expresskoa等。下面以express为例简单搭建一个http-sever

  • npm安装express
npm i express
  • 创建基本web服务器
const express = require('express');
const app = express();
app.listen(80, () => {
    console.log('http has been started');
}
  • 监听GET请求
app.get('url', callback);
  • 监听POST请求
app.post('url', callback);
  • 托管静态资源
//创建静态资源服务器
const libstatic = express.static('path');

//挂载到web服务器上对外访问
app.use(libstatic)

至此,一个最简单的基于express的web应用就搭建完成啦~