node

Node.js

CommonJS

  • CommonJS 是一种模块化规范,主要用于在服务器端(如 Node.js 环境)实现模块化编程。以下是关于 CommonJS 的详细介绍:

1. 背景

在 JavaScript 的早期,代码通常是全局共享的,没有模块化的概念。随着项目复杂度的增加,代码的可维护性和可复用性变得很差。CommonJS 规范应运而生,它旨在为 JavaScript 提供一种模块化机制,方便开发者组织代码、避免命名冲突,并提高代码的可维护性。

2. 核心概念

CommonJS 规范定义了模块的加载和导出机制,主要包括以下几个核心概念:

  • 模块(Module) :每个文件被视为一个独立的模块。模块内部的变量和函数默认不会被外部访问,除非显式导出。
  • require :用于加载模块。通过 require 函数可以引入其他模块的功能。
  • moduleexports :用于导出模块的功能。module 是一个对象,exportsmodule 的一个属性,通常用于导出模块的接口。

3. 模块的导出

在 CommonJS 中,可以通过 module.exportsexports 来导出模块的内容:

  • module.exports:可以直接导出一个对象、函数、类等。它是模块的最终导出内容。

    ini 复制代码
    // math.js
    const add = (a, b) => a + b;
    const subtract = (a, b) => a - b;
    
    module.exports = { add, subtract };
  • exportsexportsmodule.exports 的引用,可以用来导出模块的部分内容。但需要注意,如果直接覆盖 module.exportsexports 的引用会失效。

    css 复制代码
    // utils.js
    exports.add = (a, b) => a + b;
    exports.subtract = (a, b) => a - b;

4. 模块的加载

通过 require 函数加载模块:

javascript 复制代码
// app.js
const math = require('./math.js');
console.log(math.add(3, 5)); // 输出 8
console.log(math.subtract(10, 4)); // 输出 6

5. 模块缓存机制

CommonJS 模块加载时会进行缓存。当第一次加载模块时,模块的内容会被执行并缓存结果。后续再次加载时,直接返回缓存的结果,而不会重新执行模块代码。这可以提高性能,但需要注意,模块的状态是持久化的。

6. 适用场景

CommonJS 主要用于 Node.js 环境,因为它非常适合服务器端的模块化开发。Node.js 原生支持 CommonJS 规范,使得开发者可以方便地组织代码,构建大型项目。

7. 与其他模块化规范的比较

  • 与 AMD(Asynchronous Module Definition)比较:AMD 是一种异步加载模块的规范,主要用于浏览器端,支持异步加载模块,适合复杂的前端项目。CommonJS 是同步加载模块,更适合服务器端。
  • 与 ES6 模块(ESM)比较:ES6 模块是现代 JavaScript 的原生模块化规范,支持动态导入、静态分析等特性。CommonJS 是较早的规范,语法相对简单,但在现代项目中,ESM 的使用越来越广泛。

CommonJS 是 JavaScript 模块化发展的重要一步,虽然在现代前端开发中逐渐被 ES6 模块取代,但它在 Node.js 环境中仍然具有重要地位。

npm

npm(Node Package Manager)是 Node.js 生态系统中的核心工具,用于管理 JavaScript 项目中的依赖包。以下是关于 npm 的详细介绍:

npm 的功能和作用

  1. 包管理

    • 安装依赖包 :通过简单的命令(如 npm install <package>)可以快速安装项目所需的第三方库。
    • 更新和卸载包 :使用 npm update <package>npm uninstall <package> 可以方便地更新或卸载包。
    • 管理全局包 :使用 npm install -g <package> 可以将包安装到全局环境中。
  2. 版本控制

    • npm 支持语义化版本控制(SemVer),允许开发者指定依赖包的特定版本或版本范围。
    • package.json 中,可以使用符号(如 ^~)来定义版本范围。
    • package-lock.json 文件可以锁定依赖包的具体版本,确保不同开发环境的一致性。
  3. 依赖解析

    • npm 自动处理包之间的依赖关系,确保所有依赖都能正确安装。
  4. 脚本运行

    • package.jsonscripts 字段中定义自定义脚本,如构建、测试、部署等任务。
    • 使用 npm run <script-name> 可以运行这些脚本。
  5. 包发布

    • 开发者可以将自己的代码打包并发布到 npm 官方仓库。
    • 也可以搭建私有注册表,用于内部包的管理和分发。
  6. 生命周期钩子

    • npm 提供了多种生命周期钩子(如 preinstallpostinstallprepublish 等),允许在包的安装、测试、发布等过程中执行自定义脚本。

npm 的使用

  1. 安装 npm

    • npm 通常与 Node.js 一起安装。安装 Node.js 后,npm 也会随之安装。
    • 可以通过 npm -v 命令检查 npm 是否安装成功。
  2. 初始化项目

    • 使用 npm init 命令可以创建一个 package.json 文件,记录项目的元数据和依赖信息。
  3. 常用命令

    • 安装依赖:npm installnpm install <package>
    • 更新依赖:npm updatenpm update <package>
    • 卸载依赖:npm uninstall <package>
    • 查看已安装的包:npm list
    • 清除缓存:npm cache clean --force

高级用法

  1. 私有包和作用域

    • 使用作用域(如 @myorg/mypackage)可以组织相关包,并创建私有包。
    • 发布私有包需要付费账户或组织。
  2. 镜像源

    • 由于 npm 官方服务器在国外,国内用户可以使用淘宝镜像(如 cnpm)来加速包的下载。
  3. 持续集成/持续部署(CI/CD)

    • 在 CI/CD 环境中,使用 npm ci 可以严格按照 package-lock.json 安装依赖。

npm 是现代 JavaScript 开发中不可或缺的工具,它极大地提高了开发效率并简化了依赖管理。

yarn

Yarn 是一个现代的包管理工具,旨在提高 JavaScript 项目的依赖管理和安装速度。以下是 Yarn 的基本用法,包括初始化项目、安装依赖、更新依赖、运行脚本等常见操作。

1. 安装 Yarn

在安装 Yarn 之前,需要确保已经安装了 Node.js。可以通过以下命令安装 Yarn:

使用 npm 安装 Yarn:

bash复制

csharp 复制代码
npm install --global yarn
验证 Yarn 是否安装成功:

bash复制

css 复制代码
yarn --version

如果返回版本号,则表示 Yarn 已正确安装。

2. 初始化项目

在项目的根目录下运行以下命令,创建 package.json 文件:

bash复制

csharp 复制代码
yarn init

按照提示输入项目信息(如名称、版本、描述、入口文件等)。也可以使用 -y--yes 选项快速生成默认配置:

bash复制

csharp 复制代码
yarn init -y

3. 安装依赖

(1)安装项目依赖

在项目根目录下运行以下命令,安装指定的包,并将其添加到 package.jsondependencies 中:

bash复制

csharp 复制代码
yarn add <package-name>

例如:

bash复制

csharp 复制代码
yarn add express

这会在项目中安装 express 包,并在 package.json 中添加如下内容:

JSON复制

json 复制代码
"dependencies": {
  "express": "^4.18.2"
}
(2)安装开发依赖

如果某些包仅在开发环境中使用(如测试工具、构建工具等),可以将其添加到 devDependencies

bash复制

lua 复制代码
yarn add <package-name> --dev

或简写为:

bash复制

csharp 复制代码
yarn add <package-name> -D

例如:

bash复制

csharp 复制代码
yarn add jest -D
(3)安装全局包

某些工具(如 create-react-app)需要全局安装:

bash复制

csharp 复制代码
yarn global add <package-name>

例如:

bash复制

sql 复制代码
yarn global add create-react-app

4. 更新依赖

更新项目中的某个依赖包:

bash复制

go 复制代码
yarn upgrade <package-name>

更新所有依赖包:

bash复制

复制代码
yarn upgrade

5. 卸载依赖

卸载项目中的某个依赖包:

bash复制

lua 复制代码
yarn remove <package-name>

6. 运行脚本

package.jsonscripts 字段中定义脚本:

JSON复制

json 复制代码
"scripts": {
  "start": "node index.js",
  "test": "jest"
}

运行脚本:

bash复制

arduino 复制代码
yarn run <script-name>

例如:

bash复制

arduino 复制代码
yarn run start
yarn run test

也可以省略 run,直接运行:

bash复制

bash 复制代码
yarn start
yarn test

7. 查看已安装的包

查看项目中已安装的包:

bash复制

复制代码
yarn list

查看全局已安装的包:

bash复制

csharp 复制代码
yarn global list

8. 清理缓存

Yarn 会缓存已安装的包,以加快后续安装速度。如果需要清理缓存,可以运行:

bash复制

复制代码
yarn cache clean

9. 切换镜像源

由于 Yarn 默认使用的是官方源,可能会受到网络问题的影响。可以切换到国内镜像源以提高下载速度。

查询当前使用的镜像源:

bash复制

arduino 复制代码
yarn config get registry
切换到国内镜像源(如淘宝镜像):

bash复制

arduino 复制代码
yarn config set registry https://registry.npmmirror.com/
切换回官方源:

bash复制

arduino 复制代码
yarn config set registry https://registry.yarnpkg.com/

10. 其他常用命令

  • 查看包信息

    bash复制

    go 复制代码
    yarn info <package-name>
  • 搜索包

    bash复制

    sql 复制代码
    yarn search <keyword>
  • 查看 Yarn 配置

    bash复制

    arduino 复制代码
    yarn config list

11. 使用 yarn.lock 文件

Yarn 使用 yarn.lock 文件来锁定依赖版本,确保在不同机器上安装的依赖完全一致。在项目中,yarn.lock 文件会自动生成,不要手动修改它。如果需要重新生成 yarn.lock 文件,可以删除旧文件后运行:

bash复制

复制代码
yarn install

12. 离线模式

Yarn 支持离线模式,可以在没有网络的情况下安装依赖。确保本地缓存中有相关包后,运行:

bash复制

css 复制代码
yarn install --offline

通过以上命令和操作,你可以高效地使用 Yarn 来管理项目的依赖、运行脚本和发布包。Yarn 的设计目标是快速、可靠和安全,适合现代 JavaScript 项目的开发需求。

内置模块(http模块)

Node.js 的 http 模块是一个内置模块,用于创建 HTTP 服务器和客户端。它提供了底层的 HTTP 功能,允许开发者构建高性能的 HTTP 应用程序。以下是关于 Node.js 中 http 模块的详细介绍和使用方法。

1. 创建 HTTP 服务器

使用 http 模块可以轻松创建一个 HTTP 服务器。以下是一个简单的示例:

javascript 复制代码
const http = require('http');

// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
  // 设置响应头
  res.writeHead(200, { 'Content-Type': 'text/plain' });

  // 发送响应内容
  res.end('Hello, World!\n');
});

// 监听端口
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
代码解析
  • http.createServer():创建一个 HTTP 服务器实例。

    • 它接受一个回调函数,该回调函数会在每次请求到达时被调用。

    • 回调函数的参数:

      • reqhttp.IncomingMessage 对象,表示客户端的请求。
      • reshttp.ServerResponse 对象,用于向客户端发送响应。
  • res.writeHead():设置响应头,包括状态码和响应头字段。

  • res.end():结束响应,发送响应内容到客户端。

  • server.listen():让服务器监听指定的端口。

2. 处理不同的 HTTP 请求

可以通过检查 req 对象的属性来处理不同的请求路径和方法。

ini 复制代码
const http = require('http');

const server = http.createServer((req, res) => {
  const { method, url } = req;

  if (method === 'GET' && url === '/') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>Welcome to the Home Page</h1>');
  } else if (method === 'GET' && url === '/about') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>About Us</h1>');
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 Not Found');
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

3. 处理 POST 请求

处理 POST 请求时,需要从请求体中读取数据。可以通过监听 dataend 事件来实现。

javascript 复制代码
const http = require('http');

const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/submit') {
    let body = '';

    // 监听 data 事件,读取数据
    req.on('data', (chunk) => {
      body += chunk.toString();
    });

    // 监听 end 事件,处理数据
    req.on('end', () => {
      console.log('Received POST data:', body);
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(`You sent: ${body}`);
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 Not Found');
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

4. 发送 HTTP 请求(客户端)

http 模块也可以用于发送 HTTP 请求。以下是一个发送 GET 请求的示例:

javascript 复制代码
const http = require('http');

const options = {
  hostname: 'example.com',
  port: 80,
  path: '/',
  method: 'GET',
};

const req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);

  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });

  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${e.message}`);
});

// 结束请求
req.end();

5. 使用 HTTP 模块的优势

  • 轻量级http 模块是 Node.js 的内置模块,无需额外安装。
  • 高性能:基于 Node.js 的非阻塞 I/O 模型,可以处理高并发请求。
  • 灵活性:提供了底层的 HTTP 功能,可以自定义请求和响应的处理逻辑。

6. 与其他框架的比较

虽然 http 模块功能强大,但在实际开发中,通常会使用更高级的框架(如 Express.js)来简化开发过程。Express.js 基于 http 模块,提供了路由、中间件、模板引擎等高级功能,适合构建复杂的 Web 应用程序。

示例:使用 Express.js 创建服务器

ini 复制代码
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

总结

Node.js 的 http 模块是一个强大的工具,适用于构建高性能的 HTTP 服务器和客户端。它提供了底层的 HTTP 功能,允许开发者自定义请求和响应的处理逻辑

内置模块(url模块)

Node.js 的 url 模块是一个非常重要的内置模块,用于处理和解析 URL。它提供了多种方法和属性,可以帮助开发者轻松地解析、构建和操作 URL。以下是 url 模块的主要功能和用法:

1. 解析 URL

url.parse() 方法可以将一个 URL 字符串解析为一个对象,包含 URL 的各个组成部分。

ini 复制代码
const url = require('url');

const urlString = 'http://example.com:8080/path/to/file?query=123#hash';
const parsedUrl = url.parse(urlString);

console.log(parsedUrl);

输出示例:

yaml 复制代码
Url {
  protocol: 'http:',
  slashes: true,
  auth: null,
  host: 'example.com:8080',
  port: '8080',
  hostname: 'example.com',
  hash: '#hash',
  search: '?query=123',
  query: 'query=123',
  pathname: '/path/to/file',
  path: '/path/to/file?query=123',
  href: 'http://example.com:8080/path/to/file?query=123#hash'
}

2. 构建 URL

url.format() 方法可以将一个 URL 对象或字符串重新格式化为一个完整的 URL 字符串。

ini 复制代码
const url = require('url');

const urlObject = {
  protocol: 'http:',
  hostname: 'example.com',
  port: 8080,
  pathname: '/path/to/file',
  query: 'query=123',
  hash: '#hash'
};

const formattedUrl = url.format(urlObject);
console.log(formattedUrl); // 输出: http://example.com:8080/path/to/file?query=123#hash

3. 解析查询字符串

url.parse() 方法解析 URL 后,会将查询字符串部分存储在 query 属性中。如果需要进一步解析查询字符串,可以使用 querystring 模块。

ini 复制代码
const url = require('url');
const querystring = require('querystring');

const urlString = 'http://example.com/path/to/file?query=123&name=Kimi#hash';
const parsedUrl = url.parse(urlString);

const query = querystring.parse(parsedUrl.query);
console.log(query); // 输出: { query: '123', name: 'Kimi' }

4. URL 模块的现代替代:URLURLSearchParams

从 Node.js v10 开始,引入了与浏览器一致的 URLURLSearchParams API,这些 API 更现代化且功能更强大。

javascript 复制代码
const { URL, URLSearchParams } = require('url');

// 解析 URL
const urlString = 'http://example.com:8080/path/to/file?query=123#hash';
const myUrl = new URL(urlString);

console.log(myUrl.protocol); // http:
console.log(myUrl.hostname); // example.com
console.log(myUrl.port);     // 8080
console.log(myUrl.pathname); // /path/to/file
console.log(myUrl.search);   // ?query=123
console.log(myUrl.hash);     // #hash

// 解析查询字符串
const searchParams = new URLSearchParams(myUrl.search);
console.log(searchParams.get('query')); // 123

// 构建 URL
const newUrl = new URL('/path/to/file', 'http://example.com');
newUrl.search = 'query=123';
newUrl.hash = '#hash';
console.log(newUrl.href); // http://example.com/path/to/file?query=123#hash

5. 使用场景

  • 解析请求 URL:在 HTTP 服务器中,解析客户端请求的 URL,提取路径、查询参数等信息。
  • 构建响应 URL:根据业务逻辑动态生成 URL,用于重定向或生成链接。
  • 处理查询参数:方便地操作查询字符串,例如添加、删除或修改查询参数。

总结

Node.js 的 url 模块提供了丰富的功能,用于处理和解析 URL。虽然传统的 url.parse()url.format() 方法仍然可用,但推荐使用现代的 URLURLSearchParams API,因为它们更符合现代 JavaScript 的规范,并且功能更强大、更易于使用。

内置模块(querstring模块)

querystring 是 Node.js 的一个内置模块,用于处理查询字符串(URL 中的 ?key=value&... 部分)。它提供了两个主要功能:解析查询字符串和构建查询字符串。

1. 解析查询字符串

可以将查询字符串解析为一个对象。

ini 复制代码
const querystring = require('querystring');

const queryString = 'name=Kimi&age=25&city=Beijing';
const parsedQuery = querystring.parse(queryString);

console.log(parsedQuery);
// 输出:{ name: 'Kimi', age: '25', city: 'Beijing' }

2. 构建查询字符串

可以将一个对象转换为查询字符串。

ini 复制代码
const querystring = require('querystring');

const queryParams = { name: 'Kimi', age: 25, city: 'Beijing' };
const queryString = querystring.stringify(queryParams);

console.log(queryString);
// 输出:name=Kimi&age=25&city=Beijing

node 解决跨域问题

在 Node.js 中解决跨域问题(CORS)有多种方法,以下是几种常见的解决方案:

1. 使用 cors 中间件

cors 是一个专门用于解决跨域问题的 Node.js 中间件,非常简单易用。

安装

bash复制

复制代码
npm install cors
使用示例

JavaScript复制

ini 复制代码
const express = require('express');
const cors = require('cors');

const app = express();

// 允许所有来源访问
app.use(cors());

// 或者指定特定来源
app.use(cors({
  origin: 'http://example.com'
}));

app.get('/data', (req, res) => {
  res.json({ message: 'This is CORS-enabled for only example.com.' });
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

2. 手动设置响应头

如果不想使用中间件,可以直接在响应头中设置 Access-Control-Allow-Origin

示例

JavaScript复制

javascript 复制代码
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*'); // 允许所有来源
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

app.get('/data', (req, res) => {
  res.json({ message: 'This is CORS-enabled.' });
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

3. 使用 http-proxy-middleware 代理

如果需要代理请求到其他服务器,可以使用 http-proxy-middleware

安装

bash复制

复制代码
npm install http-proxy-middleware
示例

JavaScript复制

javascript 复制代码
const express = require('express');
const proxy = require('http-proxy-middleware');

const app = express();

app.use('/api', proxy({
  target: 'http://example.com', // 目标服务器
  changeOrigin: true,
  pathRewrite: {
    '^/api': '' // 重写路径
  }
}));

app.listen(3000, () => {
  console.log('Proxy server is running on port 3000');
});

4. 通过 Nginx 代理

如果使用 Nginx 作为反向代理服务器,也可以在 Nginx 配置中解决跨域问题。

Nginx 配置示例

nginx复制

ini 复制代码
server {
  listen 80;
  server_name www.domain1.com;

  location / {
    proxy_pass http://www.domain2.com; # 目标服务器
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    add_header Access-Control-Allow-Origin *; # 允许所有来源
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
    add_header Access-Control-Allow-Headers "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
  }
}

5. 使用 JSONP

虽然 JSONP 只支持 GET 请求,但在某些场景下也可以作为一种解决方案。

前端示例

JavaScript复制

php 复制代码
$.ajax({
  url: 'http://example.com/data',
  type: 'GET',
  dataType: 'jsonp',
  jsonpCallback: 'callbackFunction',
  success: function(data) {
    console.log(data);
  }
});
后端示例

JavaScript复制

ini 复制代码
const http = require('http');
const querystring = require('querystring');

const server = http.createServer((req, res) => {
  const url = new URL(req.url, `http://${req.headers.host}`);
  const params = querystring.parse(url.search.slice(1));
  const callback = params.callback;

  res.writeHead(200, { 'Content-Type': 'application/javascript' });
  res.end(`${callback}({"message": "Hello, JSONP!"})`);
server});

.listen(3000, () => {
  console.log('Server is running on port 3000');
});

总结

  • 推荐使用 cors 中间件,因为它简单且功能强大。
  • 如果需要代理请求,可以使用 http-proxy-middleware
  • 如果使用 Nginx,可以通过 Nginx 配置解决跨域问题。
  • JSONP 是一种古老的解决方案,但只支持 GET 请求,适合简单场景

内置模块(event模块)

在 Node.js 中,events 模块是一个核心模块,用于实现事件驱动编程。它提供了一个 EventEmitter 类,允许你创建可以发射(emit)和监听(listen)事件的对象。这种模式非常适合处理异步操作和事件驱动的编程场景。

1. 引入 events 模块

要使用 events 模块,首先需要引入它:

JavaScript复制

ini 复制代码
const EventEmitter = require('events');

2. 创建 EventEmitter 实例

你可以通过继承 EventEmitter 类或直接使用其实例来创建事件发射器。

示例 1:直接使用 EventEmitter 实例

JavaScript复制

javascript 复制代码
const EventEmitter = require('events');

// 创建 EventEmitter 实例
const emitter = new EventEmitter();

// 监听事件
emitter.on('greet', (message) => {
  console.log(`Received greeting: ${message}`);
});

// 发射事件
emitter.emit('greet', 'Hello, world!');
示例 2:通过继承 EventEmitter

JavaScript复制

javascript 复制代码
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('greet', (message) => {
  console.log(`Received greeting: ${message}`);
});

myEmitter.emit('greet', 'Hello, world!');

3. 常用方法

EventEmitter 提供了以下常用方法:

on(event, listener)

注册一个监听器,监听指定事件。

JavaScript复制

javascript 复制代码
emitter.on('event', (arg1, arg2) => {
  console.log(arg1, arg2);
});
emit(event, [...args])

发射一个事件,并将参数传递给监听器。

JavaScript复制

arduino 复制代码
emitter.emit('event', 'arg1', 'arg2');
once(event, listener)

注册一个一次性监听器,监听指定事件。监听器在事件第一次发射后自动移除。

JavaScript复制

javascript 复制代码
emitter.once('event', () => {
  console.log('This will be called only once.');
});
removeListener(event, listener)

移除指定事件的监听器。

JavaScript复制

ini 复制代码
const listener = () => {
  console.log('This will be removed.');
};

emitter.on('event', listener);
emitter.removeListener('event', listener);
off(event, listener)

removeListener 相同,移除指定事件的监听器。

JavaScript复制

vbnet 复制代码
emitter.off('event', listener);
removeAllListeners([event])

移除所有监听器,或者移除指定事件的所有监听器。

JavaScript复制

arduino 复制代码
emitter.removeAllListeners('event');
listeners(event)

返回指定事件的所有监听器数组。

JavaScript复制

arduino 复制代码
console.log(emitter.listeners('event'));
listenerCount(event)

返回指定事件的监听器数量。

JavaScript复制

arduino 复制代码
console.log(emitter.listenerCount('event'));

4. 事件驱动编程示例

以下是一个完整的示例,展示如何使用 events 模块实现事件驱动编程。

示例代码

JavaScript复制

javascript 复制代码
const EventEmitter = require('events');

class User extends EventEmitter {
  constructor(name) {
    super();
    this.name = name;
  }

  greet() {
    this.emit('greet', `Hello, ${this.name}!`);
  }
}

const user = new User('Kimi');
user.on('greet', (message) => {
  console.log(message);
});

user.greet(); // 输出:Hello, Kimi!

5. 注意事项

  • 事件监听器数量限制 :默认情况下,EventEmitter 对每个事件的监听器数量有限制(默认为 10)。如果需要更多监听器,可以通过 emitter.setMaxListeners(n) 设置最大监听器数量。
  • 内存泄漏:如果事件监听器没有被正确移除,可能会导致内存泄漏。建议在不需要时移除监听器。
  • 错误事件EventEmitter 提供了一个特殊的 error 事件,用于处理错误。如果没有监听 error 事件,当发射 error 事件时,程序会抛出错误并可能崩溃。
示例:监听 error 事件

JavaScript复制

javascript 复制代码
emitter.on('error', (err) => {
  console.error('Error occurred:', err.message);
});

emitter.emit('error', new Error('Something went wrong'));

总结

events 模块是 Node.js 中实现事件驱动编程的核心工具。通过 EventEmitter 类,你可以轻松地创建事件发射器,注册事件监听器,并在需要时发射事件。这种模式非常适合处理异步操作和事件驱动的场景。

相关推荐
excel3 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子10 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构17 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep18 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss22 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风23 分钟前
html二次作业
前端·html
前端双越老师23 分钟前
【干货】使用 langChian.js 实现掘金“智能总结” 考虑大文档和 token 限制
人工智能·langchain·node.js
江城开朗的豌豆26 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵26 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮29 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf