头图

Node.js 中的模块化

更多精彩内容,请微信搜索“前端爱好者戳我 查看

官网地址https://nodejs.cn/api/

fs 文件系统

地址https://nodejs.cn/api/fs.html#%E6%96%87%E4%BB%B6%E7%B3%BB%E7%...

node:fs 模块能够以标准 POSIX 函数为模型的方式与文件系统进行交互。

要使用基于 promise 的 API:

import * as fs from 'node:fs/promises';

要使用回调和同步的 API:

import * as fs from 'node:fs';

所有文件系统操作都具有同步、回调和基于 promise 的形式,并且可以使用 CommonJS 语法和 ES6 模块进行访问。

Promise 示例

基于 promise 的操作会返回一个当异步操作完成时被履行的 promise。

import { unlink } from 'node:fs/promises';

try {
  await unlink('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (error) {
  console.error('there was an error:', error.message);
}

同步示例

同步的 API 会阻塞 Node.js 事件循环和下一步的 JavaScript 执行,直到操作完成。 异常会被立即地抛出,可以使用 try…catch 来处理,也可以允许冒泡。

import { unlinkSync } from 'node:fs';

try {
  unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}

具体案例

读取文件

var fs = require('fs')

//异步读取
fs.readFile('./abc.txt', (err,data)=>{
    if(err){
        return console.error(err)
    }

    console.log('异步读取', data.toString())
})

//同步读取
var data = fs.readFileSync('./abc.txt')
console.log('同步读取',data.toString());

写入文件

var fs = require('fs')
// 同步写入
// fs.writeFileSync('./abc.txt','这是使用writeFileSync写入的内容')

console.log('start')

// 异步写入
fs.writeFile('./abc.txt','这是使用writeFile写入的内容', (err)=>{
    if(err){
        return console.error(err)
    }

    console.log('写入完毕')
})

console.log('end')

// 输出内容
start
end
写入完毕

buffer 缓冲区

地址https://nodejs.cn/api/buffer.html

buffer模块的特点

  • buffer用来处理二进制数据流
  • buffer实例类似数组,大小是固定的
  • buffer是使用C++代码在V8堆外分配的物理内存
  • Buffer是一个全局变量

Buffer 对象用于表示固定长度的字节序列。 许多 Node.js API 都支持 Buffer。

Buffer 类是 JavaScript Uint8Array 类的子类,并使用涵盖额外用例的方法对其进行扩展。 Node.js API 在支持 Buffer 的地方也接受纯 Uint8Array。

虽然 Buffer 类在全局作用域内可用,但仍然建议通过 import 或 require 语句显式地引用它。

const { Buffer } = require('node:buffer');

// Creates a zero-filled Buffer of length 10.
const buf1 = Buffer.alloc(10);

// Creates a Buffer of length 10,
// filled with bytes which all have the value `1`.
const buf2 = Buffer.alloc(10, 1);

// Creates an uninitialized buffer of length 10.
// This is faster than calling Buffer.alloc() but the returned
// Buffer instance might contain old data that needs to be
// overwritten using fill(), write(), or other functions that fill the Buffer's
// contents.
const buf3 = Buffer.allocUnsafe(10);

// Creates a Buffer containing the bytes [1, 2, 3].
const buf4 = Buffer.from([1, 2, 3]);

// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries
// are all truncated using `(value & 255)` to fit into the range 0–255.
const buf5 = Buffer.from([257, 257.5, -255, '1']);

// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':
// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)
// [116, 195, 169, 115, 116] (in decimal notation)
const buf6 = Buffer.from('tést');

// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].
const buf7 = Buffer.from('tést', 'latin1');

缓冲区和字符编码

在 Buffer 和字符串之间转换时,可以指定字符编码。 如果未指定字符编码,则默认使用 UTF-8。

let buf1 = Buffer.alloc(10)
console.log(buf1)

let buf2 = Buffer.alloc(5,1)
console.log(buf2)

let buf3 = Buffer.allocUnsafe(5)
console.log(buf3)

let buf4 = Buffer.from([1,2,3])
console.log(buf4)

let buf5 = Buffer.from('hello')
console.log(buf5)

let buf6 = Buffer.from('hello','base64')
console.log(buf6)

输出:

<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 01 01 01 01>
<Buffer 00 00 00 00 00>
<Buffer 01 02 03>
<Buffer 68 65 6c 6c 6f>
<Buffer 85 e9 65>

静态方法:Buffer.byteLength(string[, encoding])

地址https://nodejs.cn/api/buffer.html#%E9%9D%99%E6%80%81%E6%96%B9...

使用 encoding 编码时返回字符串的字节长度。 这与 String.prototype.length 不同,String.prototype.length 不考虑用于将字符串转换为字节的编码。

  • string <string> | <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <SharedArrayBuffer> 用于计算长度的值。
  • encoding <string> 如果 string 是字符串,则这就是它的编码。 默认值: 'utf8'。
  • 返回: <integer> string 中包含的字节数。

静态方法:Buffer.isBuffer(obj)

如果 obj 是 Buffer,则返回 true,否则返回 false。

  • obj <Object>
  • 返回: <boolean>
const { Buffer } = require('node:buffer');

Buffer.isBuffer(Buffer.alloc(10)); // true
Buffer.isBuffer(Buffer.from('foo')); // true
Buffer.isBuffer('a string'); // false
Buffer.isBuffer([]); // false
Buffer.isBuffer(new Uint8Array(1024)); // false

静态方法:Buffer.concat(list[, totalLength])

地址https://nodejs.cn/api/buffer.html#%E9%9D%99%E6%80%81%E6%96%B9...

返回新的 Buffer,它是将 list 中的所有 Buffer 实例连接在一起的结果。

如果列表没有条目,或者 totalLength 为 0,则返回新的零长度 Buffer。

如果未提供 totalLength,则从 list 中的 Buffer 实例通过相加其长度来计算。

如果提供了 totalLength,则将其强制为无符号整数。 如果 list 中的 Buffer 的组合长度超过 totalLength,则结果将被截断为 totalLength。

  • list <Buffer[]> | <Uint8Array[]> 要连接的 Buffer 或 Uint8Array 实例的列表。
  • totalLength <integer> 连接时 list 中 Buffer 实例的总长度。
  • 返回: <Buffer>
let length = Buffer.byteLength('hello')
console.log(length)

// isBuffer
let a = {}
let buf = Buffer.from('hello')

console.log(Buffer.isBuffer(a))
console.log(Buffer.isBuffer(buf))

//concat()
let buf1 = Buffer.from('This')
let buf2 = Buffer.from('is')
let buf3 = Buffer.from('a')
let buf4 = Buffer.from('buffer')
let buf5 = Buffer.from('demo!')

let BufObj = Buffer.concat([buf1,buf2,buf3,buf4,buf5])
console.log(BufObj.toString('base64'))

// 输出

5
false
true
VGhpc2lzYWJ1ZmZlcmRlbW8h

事件

地址https://nodejs.cn/api/events.html

许多 Node.js 核心 API 都是围绕惯用的异步事件驱动架构构建的,在该架构中,某些类型的对象(称为 "触发器")触发命名事件,导致调用 Function 对象("监听器")。

例如: 每当对等点连接到 net.Server 对象时,它都会触发一个事件; 当文件被打开时,fs.ReadStream 触发一个事件; 只要数据可供读取,流 就会触发一个事件。

所有触发事件的对象都是 EventEmitter 类的实例。 这些对象暴露了 eventEmitter.on() 函数,允许将一个或多个函数绑定到对象触发的命名事件。 通常,事件名称是驼峰式字符串,但也可以使用任何有效的 JavaScript 属性键。

当 EventEmitter 对象触发事件时,将同步调用附加到该特定事件的所有函数。 调用的监听器返回的任何值都将被忽略和丢弃。

以下示例展示了使用单个监听器的简单的 EventEmitter 实例。 eventEmitter.on() 方法用于注册监听器,eventEmitter.emit() 方法用于触发事件。

import { EventEmitter } from 'node:events';

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});
myEmitter.emit('event');

案例

const EventEmitter = require('events')

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent()

ce.on('test', () => {
    console.log('this is a test!')
})

setInterval(()=>{
    ce.emit('test')
},1000)
const EventEmitter = require('events')

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent()

ce.on('error', (err,date) => {
    console.log(err)
    console.log(date)
})

ce.emit('error', new Error('this is a error!'), Date.now())
const EventEmitter = require('events')

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent()

ce.once('test', () => {
    console.log('test event!')
})

setInterval(()=>{
    ce.emit('test')
},1000)
const EventEmitter = require('events')

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent()

function fn1(){
    console.log('fn1')
}

function fn2(){
    console.log('fn2')
}

ce.on('test',fn1)
ce.on('test',fn2)

setInterval(() => {
    ce.emit('test')
}, 500);

setTimeout(() => {
    // ce.removeListener('test',fn1)
    // ce.removeListener('test',fn2)
    ce.removeAllListeners('test')
}, 1500);

参考文档

前端爱好者


前端老兵
15 声望1 粉丝

你们说这是哪里?