Node.js 基础
Node 是什么?可以做什么?
- Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
- 可以写脚本,中间层,服务端渲染(vue,react) 可以实现前后端分离。
- 单线程, 适合 I/O 密集型应用,不适合 CPU 密集型应用。
- 实现高性能的 web 服务。
Node 全局对象
- global: 全局对象,类似于浏览器中的 window 对象。
- process: 进程对象,可以获取当前进程的信息,如环境变量,命令行参数等。
- p
rocess.env: 环境变量 - process.argv: 命令行参数
- process.nextTick: 事件循环的一部分,用于延迟执行回调函数。
- process.cwd(): 当前工作目录
- process.chdir(): 改变当前工作目录
- process.exit(): 退出进程
- process.kill(): 杀死进程
- process.memoryUsage(): 内存使用情况
- process.uptime(): 进程运行时间
- process.hrtime(): 高精度时间
- process.platform: 操作系统平台
- process.version: Node 版本
- process.versions: Node 依赖包版本
- process.pid: 进程 ID
- process.title: 进程名称
- p
- console: 控制台对象,用于向标准输出流(stdout)或标准错误流(stderr)输出字符。
- Buffer: 用于操作二进制数据流。
- module: 用于模块化,每个文件都是一个模块,每个模块都有自己的作用域。
- exports: 用于导出模块。
- require: 用于导入模块。
- __filename: 当前模块的文件名,绝对路径。
- __dirname: 当前模块的目录名,绝对路径。
- setTimeout: 延迟执行回调函数。
- setInterval: 间隔执行回调函数。
- setImmediate: 立即执行回调函数。
- clearImmediate: 清除立即执行的回调函数。
- clearTimeout: 清除延迟执行的回调函数。
- clearInterval: 清除间隔执行的回调函数。
Node 事件循环
Node.js 是单线程的,但是它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。
Node.js 事件循环是 Node.js 实现并发的一种方式,它基于事件驱动模型,用于处理异步操作。
Node.js 事件循环由以下几个部分组成:
- V8 引擎: 用于执行 JavaScript 代码。
- libuv: 用于处理 I/O 任务。
- 事件循环: 用于调度事件回调函数。
Node.js 事件循环的执行顺序如下:
- 执行全局代码,初始化执行上下文。
- 执行事件循环,执行事件回调函数。
- 退出事件循环,执行清理工作。
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
- timers: 定时器阶段,执行 setTimeout 和 setInterval 的回调函数。
- pending callbacks: 系统操作的回调函数。
- idle, prepare: 内部使用。
- poll: 轮询阶段,执行 I/O 回调函数。
- 如果轮询队列不为空,则取出队列中的回调函数并执行。
- 如果轮询队列为空,则等待回调函数被加入轮询队列并立即执行。
- 如果轮询队列为空且没有设置定时器,则执行下一步。
- check: 执行 setImmediate 的回调函数。
- close callbacks: 执行 close 事件的回调函数。
setImmediate() 对比 setTimeout()
- setImmediate() 和 setTimeout() 都是用于延迟执行回调函数。
- setImmediate() 的回调函数会在 poll 阶段执行,setTimeout() 的回调函数会在 timers 阶段执行。
- setImmediate() 的回调函数会在 setTimeout() 的回调函数之后执行。
- setImmediate() 的回调函数会在 I/O 回调函数之前执行。
process.nextTick()
- process.nextTick() 用于延迟执行回调函数,它会在事件循环的下一次循环中执行。
- process.nextTick() 的回调函数会在任何 I/O 事件之前执行。
- process.nextTick() 的回调函数会在 setTimeout() 和 setImmediate() 之前执行。
- process.nextTick() 的回调函数会在任何异步函数之前执行。
Node 模块
let str = require('./a/a') // 默认会自动添加 .js 后缀 .json .node
// - Module._load 加载模块
// - Module._resolveFilename 解析绝对路径
// 1) 要先将 ./a的文件转化为绝对路径
// 2) 读取这个文件, 需要增加一个函数 函数内部需要返回module.exports
// 3) 让函数执行
// 4) new Module 创建模块 根据文件名来创建 exports id
// module.load 加载模块
// Module._extensions 代表的是一个对象 对象上放着很多处理的方法
// exports, require, module, __filename, __dirname
// 4) 最终返回的是module.exports
- commonjs 规范
- 一个文件就是一个模块
- 如果模块想给别人使用 module.exports exports 同一个对象但是最终导出的是 module.exports
- 如果想使用这个模块 require (同步读取文件,包一个自执行函数,vm.runInthisContext,传入 export 对象,最终返回的是 exports 对象,所以就可以拿到其他模块的内容)
- 模块的查找规范
- 第三方模块 module.paths
- 如果文件和文件夹重名 先取文件,文件不能取到,找文件夹 package.json = main = index.js**
Node 常用内置模块
path 模块
- path.basename(path[, ext]): 返回 path 的最后一部分,如果指定了 ext,则会将最后一部分的扩展名去掉。
- path.dirname(path): 返回 path 的目录名。
- path.extname(path): 返回 path 的扩展名。
- path.isAbsolute(path): 判断 path 是否为绝对路径。
- path.join([...paths]): 将所有的 path 拼接起来,并返回拼接后的路径。
- path.normalize(path): 规范化 path,解析 '..' 和 '.' 片段。
- path.parse(path): 返回 path 的对象。
- path.relative(from, to): 返回从 from 到 to 的相对路径。
- path.resolve([...paths]): 将所有的 path 拼接起来,并返回拼接后的绝对路径。
- path.sep: 返回操作系统的路径分隔符。
- path.delimiter: 返回操作系统的环境变量分隔符。
fs 模块
- fs.appendFile(path, data[, options], callback): 追加文件内容。
- fs.chmod(path, mode, callback): 修改文件权限。
- fs.chown(path, uid, gid, callback): 修改文件所有者。
- fs.close(fd, callback): 关闭文件。
- fs.copyFile(src, dest[, flags], callback): 复制文件。
- fs.createReadStream(path[, options]): 创建可读流。
- fs.createWriteStream(path[, options]): 创建可写流。
- fs.existsSync(path, callback): 检查文件是否存在。
- fs.readFileSync(path[, options]): 同步读取文件。
- fs.readFile(path[, options], callback): 异步读取文件。
util 模块
- util.inherits(constructor, superConstructor): 继承。
- util.inspect(object[, options]): 将对象转换为字符串。
- util.promisify(original): 将异步函数转换为返回 Promise 的函数。
- util.callbackify(original): 将返回 Promise 的函数转换为异步函数。
- util.format(format[, ...args]): 格式化字符串。
- util.deprecate(fn, message[, code]): 弃用函数。
- util.types: 内置类型。
- util.TextDecoder: 文本解码器。
event 模块
- eventEmitter.on(eventName, listener): 添加事件监听器。
- eventEmitter.once(eventName, listener): 添加一次性事件监听器。
- eventEmitter.off(eventName, listener): 移除事件监听器。
- eventEmitter.emit(eventName[, ...args]): 触发事件。
- eventEmitter.listenerCount(eventName): 返回事件监听器的数量。
- eventEmitter.listeners(eventName): 返回事件监听器的数组。
- eventEmitter.rawListeners(eventName): 返回事件监听器的数组,包含原始监听器。
- eventEmitter.setMaxListeners(n): 设置事件监听器的最大数量。
- eventEmitter.getMaxListeners(): 返回事件监听器的最大数量。
- eventEmitter.prependListener(eventName, listener): 添加事件监听器到监听器数组的开头。
- eventEmitter.prependOnceListener(eventName, listener): 添加一次性事件监听器到监听器数组的开头。
- eventEmitter.eventNames(): 返回事件名称的数组。
http 模块
- http.createServer([options][, requestListener]): 创建 HTTP 服务器。
- http.request(options[, callback]): 创建 HTTP 客户端。
- http.get(options[, callback]): 创建 HTTP 客户端。
- http.METHODS: HTTP 方法。
- http.STATUS_CODES: HTTP 状态码。
- http.Agent: HTTP 代理。
- http.globalAgent: 全局 HTTP 代理。
- http.ClientRequest: HTTP 客户端请求。
- http.ServerResponse: HTTP 服务器响应。
- http.IncomingMessage: HTTP 请求消息。
- http.Server: HTTP 服务器。
- http.Client: HTTP 客户端。
- http.ServerTimeoutError: HTTP 服务器超时错误。
- http.ClientTimeoutError: HTTP 客户端超时错误。