Skip to content

核心API

全局对象

global

在浏览器全局定义变量会使用window,在Nodejs中会有一些差异,使用global作为全局对象。 在ECMAScript2020为了消除差异化,统一了新的全局关键字globalThis,所以global === globalThis

  • Nodejs环境中globalThis会切换成global
  • 在浏览器会被切换为window

__dirname & __filename

Nodejs使用的CommonJS规范,会将模块封装为一个函数,在这个函数里,会传递__dirname__filename这两个参数

  • __dirname表示当前模块的所在目录的绝对路径。
  • __filename表示当前模块的所在文件的绝对路径。

require

封装模块函数传递来的参数,用于引入加载模块。

module

封装模块函数传递来的参数,用于对外输出接口。

更多对象

  • Date
  • Promise
  • Buffer
  • setTimeout
  • setImmediate
  • setInterval
  • fetch
  • Math
  • console

常用内置模块

path

UNIX系统遵循POSIX标准,而Windows只有部分实现。这就导致不同系统之间的差异化。当一套代码在不同的平台系统运行时,路径的兼容问题难以得到解决。

Nodejs中封装好了这么一套API,屏蔽了这些差异,我们只需要关注模块中的API的用法即可。

路径信息

  • basename:返回文件名的最后部分,一般是文件名

    js
    const { resolve, basename } = require("path");
    
    const filepath = resolve(__dirname, `../data/data.json`);
    
    console.log(basename(filepath)); // data.json
  • dirname:返回文件中目录的部分

    js
    const { resolve, dirname } = require("path");
    
    const filepath = resolve(__dirname, `../data/data.json`);
    
    console.log(dirname(filepath)); // /Users/xxx/codes/node/src/data
  • extname:返回文件的扩展名

    js
    const { resolve, extname } = require("path");
    
    const filepath = resolve(__dirname, `../data/data.json`);
    
    console.log(extname(filepath)); // .json

序列化

  • parse、format:将文件路径序列化成一个对象或者将对象序列化为路径

    js
    const { resolve, parse ,format} = require("path");
    
    const filepath = resolve(__dirname, `../data/data.json`);
    
    const parseStr = parse(filepath)
    const formatStr = format(parseStr)
    
    console.log(parseStr);
    console.log(formatStr)
    // /Users/xxx/codes/node/src/data/data.json
    // {
    //   root: '/',
    //   dir: '/Users/xxx/codes/node/src/data',
    //   base: 'data.json',
    //   ext: '.json',
    //   name: 'data'
    // }
  • isAbsolute:判断文件是否为绝对路径

js
const { resolve, isAbsolute } = require("path");

const filepath = resolve(__dirname, `../data/data.json`);

console.log(isAbsolute(filepath)) // true
console.log(isAbsolute('../data/data.json')) // false

拼接

  • join:根据传递的参数,从左到右拼接起来,遇到相对地址,会先拼接再运算地址。

    js
    const { join } = require("path");
    
    console.log(join("/data", "../Users/xxx/codes/node/src", "data.json"));
    // /Users/xxx/codes/node/src/data.json
  • resolve:

    • 从右到左处理传入的路径片段,直到构造出一个绝对路径。
    • 如果处理完所有路径片段后仍未生成绝对路径,则会将当前工作目录作为起点。
    • 遇到绝对路径时,构造过程会从该绝对路径开始,忽略其左边的所有路径片段。
    js
    const { resolve } = require("path");
    
    console.log(resolve("./data", "../Users/xxx/codes/node/src", "data.json"));
    // /Users/xxx/codes/node/Users/xxx/codes/node/src/data.json
    
    console.log(resolve("../data", "data.json"));
    // /Users/xxx/codes/data/data.json

event

事件触发器,是一个EventEmitter类,原理是采用了发布订阅设计模式Publisher发布者和Subscriber订阅者并不直接联系,当一个发布者有新消息时,就将这个消息发布到调度中心。调度中心就会将这个消息通知给所有订阅者。

Nodejs 中的事件对象都是 EventEmitter 对象的实例,是事件管理的通用机制,在 Nodejs 中多数模块都继承了事件,如 fs、http 、stream

事件触发器常用的方法:

  • on:将监听的事件加入到监听器数组的末尾
  • addListener:实际上是on方法的别名
  • emit:按注册顺序同步地调用为名为 eventName 的事件注册的每个监听器,并将提供的参数传给每个监听器。
  • removeListener:移除监听事件
  • off:实际上是removeListener方法的别名
  • removeAllListeners:移除所有监听事件
  • once:添加一次性的监听事件,在下次触发时,会先移除再触发此监听器
  • newListener:事件,用onaddListener,在添加新监听器时触发
  • removeListener:同newListener事件,在删除现有监听器时触发

基本使用

我们可以注册多个事件监听,并在合适的时机触发这些事件:

js
const EventEmitter = require("node:events");
const fs = require("node:fs");
const path = require("node:path");

const eventEmitter = new EventEmitter();

const filePath = path.resolve(__dirname, "../data/data.json");

// 监听事件处理函数
const listener = (type) => {
  console.log(`listener: ${type}`);
};

// 监听事件 on | addEventListener
eventEmitter.on("read", listener);

// 监听一次事件
eventEmitter.once("once", listener);

fs.readFile(filePath, (err, data) => {
  if (err) {
    console.log(err);
    return;
  }

  eventEmitter.emit("once", "once");

  // 触发事件,并传递数据
  eventEmitter.emit("read", "read");

  setTimeout(() => {
    // 取消监听 off | removeListener,需要指定事件名和监听器处理事件
    eventEmitter.off("read", listener);
  }, 1000);
});

如果多个事件被添加到监听队列中,取消监听时,将会取消最近的那次监听,比如下面的🌰:

js
// 监听事件处理函数
const listener = (type) => {
  console.log(`listener: ${type}`);
};

// 监听一次事件
ee.once("read", listener);

// 监听事件
ee.on("read", listener);

// 取消监听
// ee.off("read", listener);

ee.emit("read", "read");

分别是取消监听和不取消监听的表现

Pasted image 20250106182825.png

自定义事件

通过继承EventEmitter类,可以对象拥有事件触发器的能力

下面的 🌰 ,每次实例化对象都会触发一个监听器事件:

js
const EventEmitter = require("node:events");

class Person extends EventEmitter {
  constructor(name) {
    super();
    super.on("new", () => {
      console.log(`this class will be created by ${name}`);
    });
    this.name = name;
    super.emit("new", name);
  }
}

const lili = new Person("lili");
const lilei = new Person("lilei");

TIP

Nodejs中很多的API都是由事件触发器去协助完成的,比如文件流Streamhttp模块等。

process

获取 进程运行时信息 并控制 进程行为。是Nodejs操作当前进程和控制当前进程的API,并挂载到全局下。

高频 API

API用途
process.arch返回操作系统的CPU架构
process.cwd()返回当前工作目录
process.argv获取执行进程后的参数,返回一个数组,比如node --help,会返回--help
process.memoryUsage()获取当前进程的内存情况
process.exit(code)强制终止进程(code=0表示成功退出)
process.kill(pid)杀死一个指定的进程
process.env()读取、设置环境变量,在Windows系统下调用SET命令,在macos下则是调用export命令设置环境变量

其他模块

模块功能关键API用途
os操作系统信息os.cpus()获取CPU核心数
os.networkInterfaces()获取网络信息
os.platform() 返回标识为其编译 Node.js 二进制文件的操作系统平台的字符串。(返回值darwin:macos,win32:windows,其他:Linux)
util内置工具函数util.promisify()Nodejs大多数API遵循回调函数的方式,该API可以将回调转为Promise的形式。返回Promise
util.callbackify()与promisify正好反过来,将一个Promise转为回调的形式。
util.format()格式化输出语句。
console控制台输出console.log(...args)控制台标准输出语句
console.table(...args)表格化打印对象

模拟promisify实现

js
// 1.promisify 接受一个函数作为参数,返回一个新的函数
const myPromisify = (originalFn) => {
  return (...args) => {
    // 2. 新的函数会返回一个Promise
    return new Promise((resolve, reject) => {
      // 3. 在Promise中调用原函数,并将resolve和reject作为参数传入
      originalFn(...args, (err, ...values) => {
        if (err) {
          reject(err);
        }

        // 4.存在多个结果时,迭代返回,否则直接返回values
        if (values && values.length > 1) {
          let obj = {};
          for (let key in values) {
            obj[key] = values[key];
          }
          resolve(obj);
        } else {
          resolve(values[0]);
        }
      });
    });
  };
};

const execPromise = myPromisify(exec);

async function fn() {
  const data = await execPromise("node -v");
  console.log(data);
}

fn();

如有转载或 CV 的请标注本站原文地址