前端面试题目(Node.JS-Express框架)[一]

Express 在处理异步操作时,如何避免内存泄漏?

在Express中处理异步操作时,避免内存泄漏的关键在于确保所有异步资源都被正确管理和释放。以下是一些最佳实践:

  • 使用try-catch-finally结构:在异步操作中,使用try-catch来捕获和处理错误,同时在finally块中释放资源,如关闭数据库连接、文件句柄等。
  • 避免全局变量:全局变量会在整个应用程序的生命周期内持续存在,如果不小心将异步操作的结果存储在全局变量中,可能会导致内存无法释放。
  • 使用Promise或async/await:这些机制可以更好地管理异步流程,并确保在异步操作完成后正确释放资源。例如,使用Promise的.then()和.finally()方法,或者使用async/await配合try-catch-finally结构。
  • 定期清理不再使用的对象:使用弱引用(如WeakMap或WeakSet)来存储可能不再需要的对象,或者定期遍历并删除不再使用的对象。
  • 监控内存使用:使用Node.js的内置模块(如os或process)或第三方工具来监控内存使用情况,及时发现并处理内存泄漏问题。

Express 中如何实现多进程、多线程的支持?

Express本身是基于Node.js的,而Node.js是单线程的。但是,可以通过以下方式实现多进程或多线程的支持:

  • 多进程

    • 使用Node.js的cluster模块:该模块允许你轻松地创建多个工作进程(workers),它们共享相同的服务器端口。主进程(master)负责监听新的连接,并将它们分发给工作进程进行处理。
    • 使用外部负载均衡器:如Nginx或HAProxy,将请求分发到多个Node.js实例上。每个实例都可以运行一个Express应用程序。
  • 多线程 :虽然Node.js本身不支持多线程,但你可以使用像worker_threads这样的模块来创建多线程环境。然而,在Express应用程序中直接使用多线程可能并不常见,因为多线程编程通常比单线程编程更复杂,且Node.js的异步I/O模型已经很好地解决了并发问题。

Express 内部是如何处理路由匹配的,底层机制是什么?

Express内部的路由匹配机制是基于中间件和路由表的。当Express应用程序接收到一个请求时,它会按照定义的路由表的顺序进行匹配。每个路由都有一个路径(path)和一个或多个处理函数(handlers)。

  • 中间件:中间件函数是Express应用程序的核心组件之一。它们可以访问请求对象(req)、响应对象(res)和应用程序的请求/响应循环中的下一个中间件函数(next)。中间件函数可以执行任何代码,修改请求和响应对象,结束请求-响应循环,或调用下一个中间件函数。
  • 路由表:Express使用一个内部数据结构(通常是一个对象或数组)来存储路由信息。当请求到达时,Express会遍历这个路由表,找到与请求路径匹配的第一个路由,并执行与该路由关联的处理函数。

如何在 Express 中实现自定义的请求解析器?

在Express中实现自定义的请求解析器通常涉及编写中间件函数来解析请求体(body)。以下是一个简单的示例:

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

// 自定义请求解析器中间件
app.use((req, res, next) => {
  const contentType = req.headers['content-type'];

  if (contentType && contentType.includes('application/json')) {
    // 假设请求体是JSON格式的,我们将其解析为JavaScript对象
    let body = '';
    req.on('data', chunk => {
      body += chunk.toString();
    });
    req.on('end', () => {
      try {
        req.body = JSON.parse(body);
        next(); // 解析成功后调用next()函数将控制权传递给下一个中间件或路由处理函数
      } catch (error) {
        res.status(400).json({ error: 'Invalid JSON' });
      }
    });
  } else {
    // 如果不是JSON格式的请求体,则直接调用next()函数继续处理
    next();
  }
});

// 使用自定义解析器的路由处理函数
app.post('/example', (req, res) => {
  console.log(req.body); // 在这里可以访问解析后的请求体
  res.json({ message: 'Request body received' });
});

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

请注意,这个示例中的自定义解析器是非常基本的,并且没有处理诸如大文件上传、流式解析或错误处理等复杂情况。在实际应用中,你可能希望使用更健壮的解析器库(如body-parserexpress.json()/express.urlencoded()等内置中间件)。

如何在 Express 中进行性能监控和分析?

在Express中进行性能监控和分析可以通过多种方式实现,包括但不限于:

  • 使用内置模块 :Node.js的内置模块(如osprocessperformance)提供了关于系统性能、进程性能和代码执行时间的信息。
  • 第三方监控工具:有许多第三方工具和服务可以帮助你监控和分析Express应用程序的性能,如New Relic、Datadog、Prometheus等。这些工具通常提供了丰富的监控指标、警报功能和可视化界面。
  • 日志记录:通过在代码的关键位置添加日志记录语句,可以收集有关请求处理时间、错误发生情况和系统状态的详细信息。然后,你可以使用日志分析工具(如ELK Stack)来分析和可视化这些日志数据。
  • 性能分析工具 :使用性能分析工具(如Node.js的--inspect标志、Chrome DevTools或第三方工具如clinic)来分析应用程序的性能瓶颈和内存使用情况。

Express 中如何实现 HTTP/2 的支持?

要在Express中实现HTTP/2的支持,你需要使用支持HTTP/2的Node.js版本和相应的HTTP/2服务器实现。以下是一个简单的示例:

javascript 复制代码
const express = require('express');
const http2 = require('http2');
const fs = require('fs');
const path = require('path');

const app = express();

// 设置HTTP/2服务器选项
const serverOptions = {
  key: fs.readFileSync(path.join(__dirname, 'server-key.pem')),
  cert: fs.readFileSync(path.join(__dirname, 'server-cert.pem'))
};

// 创建HTTP/2服务器并传入Express应用程序
const server = http2.createSecureServer(serverOptions, app);

// 定义路由
app.get('/', (req, res) => {
  res.send('Hello HTTP/2!');
});

// 启动服务器
server.listen(3000, () => {
  console.log('HTTP/2 server is running on port 3000');
});

请注意,在这个示例中,我们使用了HTTPS来加密HTTP/2连接。因此,你需要提供SSL/TLS证书和私钥文件(server-key.pemserver-cert.pem)。在生产环境中,你应该使用由受信任的证书颁发机构(CA)签发的证书。

Express 中如何处理大规模的文件存储和管理?

在Express中处理大规模的文件存储和管理时,你需要考虑以下几个方面:

  • 文件存储位置:选择适当的文件存储位置(如本地磁盘、网络文件系统NFS、云存储服务等)。
  • 文件命名和目录结构:设计合理的文件命名规则和目录结构,以避免文件名冲突和方便文件查找。
  • 文件上传和下载 :使用中间件(如multer)来处理文件上传,并提供文件下载的API接口。
  • 文件访问权限:确保只有授权的用户才能访问和下载文件。你可以使用身份验证和授权机制来实现这一点。
  • 文件缓存和CDN:为了提高文件访问速度,可以考虑使用缓存机制(如内存缓存、Redis等)和CDN服务来分发文件。
  • 文件删除和清理:定期删除不再需要的文件,以避免磁盘空间被耗尽。你可以使用定时任务或文件系统的钩子函数来实现这一点。

下面是对问题的详细解答以及相关的示例代码。


1. Express 中如何实现请求队列和异步处理?

在 Express 中,可以通过使用 Promise 或其他异步控制机制实现请求队列。以下是实现请求队列的一个方法:

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

let requestQueue = []; // 请求队列
let processing = false; // 是否正在处理

// 模拟异步处理
const processRequest = async (reqData) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`Processed: ${reqData}`);
      resolve();
    }, 2000); // 模拟耗时任务
  });
};

// 中间件实现请求队列
app.use(async (req, res, next) => {
  requestQueue.push(req);

  if (!processing) {
    processing = true;

    while (requestQueue.length > 0) {
      const currentReq = requestQueue.shift();
      await processRequest(currentReq.url); // 处理请求
    }

    processing = false;
  }

  next();
});

// 示例路由
app.get('/queue', (req, res) => {
  res.send('Your request is being processed');
});

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

2. 如何在 Express 中使用 Morgan 记录日志?

Morgan 是一个流行的 HTTP 请求日志记录中间件,支持多种格式。

示例代码
javascript 复制代码
const express = require('express');
const morgan = require('morgan');

const app = express();

// 使用 Morgan 日志中间件
app.use(morgan('combined')); // 使用 'combined' 格式

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

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

Morgan 支持不同的日志格式,如 tinyshortcombined 等,也可以通过函数自定义日志格式。


3. Express 中如何实现自定义的错误页面?

通过 Express 的错误处理中间件,可以实现自定义的错误页面。

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

// 示例路由
app.get('/', (req, res) => {
  throw new Error('Something went wrong'); // 模拟错误
});

// 自定义错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack); // 打印错误堆栈
  res.status(500).send(`
    <h1>500 - Internal Server Error</h1>
    <p>${err.message}</p>
  `);
});

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

4. 在 Express 中如何使用 Helmet 提高安全性?

Helmet 是一个帮助 Express 应用程序设置 HTTP 安全头的中间件,可以防止常见的安全威胁。

示例代码
javascript 复制代码
const express = require('express');
const helmet = require('helmet');

const app = express();

// 使用 Helmet 中间件
app.use(helmet());

app.get('/', (req, res) => {
  res.send('Helmet is protecting this app!');
});

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

Helmet 提供了一系列功能,比如 contentSecurityPolicydnsPrefetchControlframeguard 等,可以单独启用或配置。


5. 如何在 Express 中处理压缩响应数据?

通过使用 compression 中间件,可以压缩响应数据,提高性能。

示例代码
javascript 复制代码
const express = require('express');
const compression = require('compression');

const app = express();

// 使用 compression 中间件
app.use(compression());

app.get('/', (req, res) => {
  res.send('This is compressed!');
});

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

6. Express 中如何实现请求参数的验证和校验?

可以使用 express-validator 或类似的库对请求参数进行验证。

示例代码
javascript 复制代码
const express = require('express');
const { body, validationResult } = require('express-validator');

const app = express();
app.use(express.json());

// 路由验证示例
app.post(
  '/user',
  body('email').isEmail().withMessage('Invalid email address'),
  body('password').isLength({ min: 5 }).withMessage('Password must be at least 5 characters long'),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    res.send('User data is valid');
  }
);

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

7. Express 如何与 TypeScript 集成,需注意哪些问题?

关键点
  1. 安装必要的依赖:

    bash 复制代码
    npm install typescript @types/express ts-node-dev @types/node
  2. 配置 tsconfig.json 文件,设置 esModuleInteroptrue 以支持导入。

  3. 在代码中显式声明类型,避免隐式 any

示例代码
typescript 复制代码
import express, { Request, Response } from 'express';

const app = express();

app.get('/', (req: Request, res: Response) => {
  res.send('Express with TypeScript!');
});

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

8. 如何在 Express 中实现自定义的 HTTP 方法?

Express 支持自定义 HTTP 方法,可以通过 app.all() 或中间件处理任意方法,也可以通过 router 实现扩展。

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

// 自定义 HTTP 方法示例
app.use((req, res, next) => {
  if (req.method === 'CUSTOM') {
    res.send('Custom HTTP Method Handled');
  } else {
    next();
  }
});

app.all('*', (req, res) => {
  res.send(`Unhandled method: ${req.method}`);
});

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

// 测试:使用 curl 模拟 CUSTOM 方法
// curl -X CUSTOM http://localhost:3000

以上是对每个问题的详细解答和对应的示例代码,适用于实际开发中的各种场景。

在 Express 中,可以通过 Node.js 的 cluster 模块实现集群模式。集群模式允许利用多核 CPU 的全部能力,将应用分散到多个子进程中运行,从而提高性能。

实现集群模式的步骤

  1. 使用 cluster 模块创建主进程和子进程

    • 主进程负责管理和分发请求。
    • 子进程运行实际的 Express 应用程序。
  2. 自动根据 CPU 核心数生成子进程

  3. 使用进程间通信(IPC)确保负载均衡


示例代码

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

if (cluster.isMaster) {
  // 获取 CPU 核心数
  const numCPUs = os.cpus().length;
  console.log(`Master process is running (PID: ${process.pid})`);
  console.log(`Forking ${numCPUs} workers...`);

  // 为每个 CPU 核心创建一个工作进程
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // 监听子进程退出事件
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} exited. Starting a new worker...`);
    cluster.fork(); // 创建新工作进程
  });
} else {
  // 子进程逻辑
  const app = express();

  app.get('/', (req, res) => {
    res.send(`Hello from worker ${process.pid}`);
  });

  app.listen(3000, () => {
    console.log(`Worker ${process.pid} started`);
  });
}

运行效果

  1. 主进程根据 CPU 核心数生成多个子进程。
  2. 子进程共享同一个端口(例如 3000),但操作系统会负责将请求分发给不同的子进程。
  3. 每个子进程独立运行,崩溃时主进程会重新启动它。

如何验证集群模式的效果?

  1. 多次刷新浏览器

    通过浏览器访问 http://localhost:3000,可以看到每次请求可能由不同的 worker 处理(打印的 PID 会不同)。

  2. 压力测试

    使用工具如 ab(Apache Benchmark)或 wrk 测试应用的并发能力:

    bash 复制代码
    ab -n 1000 -c 100 http://localhost:3000/

    集群模式下,吞吐量会显著提升。


注意事项

  1. 状态管理

    • 子进程之间是独立的,无法直接共享内存中的数据。
    • 如果需要共享数据,建议使用外部存储,如 Redis 或数据库。
  2. 负载均衡

    • cluster 模块本身会自动均衡负载,但可以结合反向代理工具(如 Nginx 或 HAProxy)进一步优化。
  3. 日志管理

    • 各子进程的日志输出可能混在一起。建议使用专门的日志工具(如 Winston)来集中管理日志。
  4. 调试复杂性

    • 子进程间的调试比单进程模式复杂,需要合理规划。

通过 cluster 模块,Express 应用可以充分利用多核 CPU 的能力,实现性能的大幅提升。

Express 在处理请求和响应时的内部流程

Express 在处理请求和响应时的内部流程大致如下:

  1. 监听请求

    • 当服务器启动时,Express 应用会监听一个指定的端口,等待客户端发送请求。
    • 当请求到达时,Node.js 的 HTTP 模块会捕获这个请求,并将其传递给 Express 应用。
  2. 中间件处理

    • Express 应用会按照定义的中间件函数的顺序来处理请求。
    • 中间件函数可以访问请求对象(req)、响应对象(res)和下一个中间件函数(next)。
    • 中间件可以对请求和响应对象进行修改,或者调用 next() 函数将控制权传递给下一个中间件。
  3. 路由匹配

    • 一旦中间件处理完毕,Express 会根据定义的路由来匹配请求的路径和方法。
    • 如果找到匹配的路由,则执行该路由对应的处理函数(也称为路由处理器)。
  4. 响应发送

    • 路由处理器会生成一个响应,并通过响应对象(res)将其发送回客户端。
    • 响应可以是文本、HTML、JSON 或其他格式的数据。
  5. 请求结束

    • 一旦响应被发送,请求/响应循环就会结束,Express 应用会等待下一个请求的到来。

示例代码(Express 处理请求和响应)

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

// 中间件示例
app.use((req, res, next) => {
  console.log('请求时间:', new Date());
  next(); // 将控制权传递给下一个中间件或路由处理器
});

// 路由处理器示例
app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(3000, () => {
  console.log('服务器正在监听端口 3000');
});

Express 与其他框架(如 Socket.io)集成

Express 与 Socket.io 集成的底层原理是共享同一个 HTTP 服务器实例。具体步骤如下:

  1. 创建 HTTP 服务器 :使用 Express 的 listen 方法或 http.createServer 方法创建一个 HTTP 服务器实例。
  2. 集成 Socket.io:将 HTTP 服务器实例传递给 Socket.io 的构造函数,以创建一个 Socket.io 实例。

示例代码(Express 与 Socket.io 集成)

javascript 复制代码
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// Express 路由
app.get('/', (req, res) => {
  res.send('Hello, Express and Socket.io!');
});

// Socket.io 事件处理
io.on('connection', (socket) => {
  console.log('新客户端已连接');
  socket.on('message', (msg) => {
    console.log('收到消息:', msg);
    io.emit('message', msg); // 向所有客户端广播消息
  });
  socket.on('disconnect', () => {
    console.log('客户端已断开连接');
  });
});

server.listen(3000, () => {
  console.log('服务器正在监听端口 3000');
});

在 Express 中实现负载均衡和高可用性

在 Express 中实现负载均衡和高可用性通常需要使用反向代理服务器(如 Nginx 或 HAProxy)和集群模块(Node.js 的 cluster 模块)。

  • 反向代理服务器:负责将客户端的请求分发到多个后端服务器(即多个 Express 应用实例)上,以实现负载均衡。
  • 集群模块:允许你创建多个工作进程来共享同一个服务器端口,从而提高应用的性能和可用性。

示例代码(使用 Node.js 的 cluster 模块)

javascript 复制代码
const cluster = require('cluster');
const os = require('os');
const express = require('express');
const numCPUs = os.cpus().length;

if (cluster.isMaster) {
  console.log(`主进程 ${process.pid} 正在运行`);

  // Fork 工作进程
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
    // 可以选择重新 fork 一个新的工作进程
    cluster.fork();
  });

} else {
  // 工作进程中的代码
  const app = express();

  app.get('/', (req, res) => {
    res.send('Hello, World! from worker ' + cluster.worker.id);
  });

  const server = app.listen(3000);

  server.on('listening', () => {
    console.log(`工作进程 ${process.pid} 正在监听端口 3000`);
  });
}

Express 4 相比老版本的区别及升级注意事项

  • 不再依赖 Connect:Express 4 不再直接依赖 Connect,而是使用自己的中间件系统。
  • 路由系统增强 :Express 4 提供了更灵活的路由定义方式,如使用 app.route() 方法。
  • 移除了一些内建中间件 :如 express.bodyParser()express.cookieParser()express.compress() 等,需要使用第三方中间件替代。
  • 升级注意事项
    • 确保所有依赖项都与 Express 4 兼容。
    • 更新中间件和路由定义以符合 Express 4 的 API。
    • 测试应用以确保一切功能正常。

在升级时,建议逐步进行,并在每个步骤后都进行充分的测试,以确保应用的稳定性和正确性。

1. Express 中间件的顺序对应用有什么影响,如何管理?

中间件顺序的影响
  • 顺序决定处理流程:Express 中间件按照声明的顺序执行,请求和响应会依次通过这些中间件。
  • 错误处理的位置:错误处理中间件必须在其他普通中间件之后,否则无法捕获错误。
  • 匹配机制:Express 按路径匹配中间件,声明顺序决定路径是否能触发特定的中间件。
管理中间件的方式
  1. 明确顺序
    • 按照逻辑分组,例如日志 -> 身份验证 -> 路由处理。
  2. 模块化管理
    • 将中间件拆分成独立模块,使用 app.use() 引入。
  3. 使用路由级别中间件
    • 绑定特定路由的中间件,避免对无关路由的干扰。
示例代码
javascript 复制代码
const express = require('express');
const app = express();

// 全局日志中间件
app.use((req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  next();
});

// 身份验证中间件
app.use('/secure', (req, res, next) => {
  const auth = req.headers.authorization;
  if (auth === 'Bearer valid-token') {
    next();
  } else {
    res.status(401).send('Unauthorized');
  }
});

// 路由
app.get('/', (req, res) => res.send('Public route'));
app.get('/secure', (req, res) => res.send('Secure route'));

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

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

2. 在 Express 中如何实现应用级别、路由级别和错误处理中间件?

应用级别中间件
  • 绑定到 app 实例。

  • 示例:

    javascript 复制代码
    app.use(express.json());
路由级别中间件
  • 绑定到特定路由。

  • 示例:

    javascript 复制代码
    app.get('/example', (req, res, next) => {
      console.log('Route-specific middleware');
      next();
    });
错误处理中间件
  • 必须有 err 参数。

  • 示例:

    javascript 复制代码
    app.use((err, req, res, next) => {
      res.status(500).send(`Error: ${err.message}`);
    });
完整代码
javascript 复制代码
const express = require('express');
const app = express();

// 应用级别中间件
app.use(express.json());

// 路由级别中间件
app.get('/user', (req, res, next) => {
  console.log('Fetching user...');
  next();
}, (req, res) => {
  res.send({ name: 'John Doe' });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something went wrong');
});

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

3. 在 Express 中如何处理子域和虚拟主机?

处理子域

可以通过 vhost 模块或 req.subdomains 实现子域处理。

示例:子域
javascript 复制代码
const express = require('express');
const app = express();

// 子域解析
app.use((req, res, next) => {
  console.log(req.subdomains); // 解析子域
  next();
});

app.get('/', (req, res) => res.send('Root domain'));
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
处理虚拟主机

使用 vhost 模块。

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

const app = express();

const subApp = express();
subApp.get('/', (req, res) => res.send('Welcome to sub.example.com'));

app.use(vhost('sub.example.com', subApp));

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

4. 如何在 Express 中使用环境变量和配置文件?

步骤
  1. 安装 dotenv

    bash 复制代码
    npm install dotenv
  2. 创建 .env 文件

    env 复制代码
    PORT=3000
    API_KEY=your-api-key
  3. 加载环境变量

    javascript 复制代码
    require('dotenv').config();
    console.log(process.env.PORT);

5. 在 Express 中如何实现数据的分页和排序?

实现分页

通过查询参数实现分页和排序。

javascript 复制代码
app.get('/items', (req, res) => {
  const { page = 1, limit = 10, sort = 'asc' } = req.query;
  const startIndex = (page - 1) * limit;
  const endIndex = startIndex + limit;

  // 模拟数据
  const items = Array.from({ length: 100 }, (_, i) => i + 1);
  const result = items.slice(startIndex, endIndex);

  res.send({
    page: parseInt(page),
    limit: parseInt(limit),
    sort,
    data: result,
  });
});

6. Express 中如何实现应用的热更新?

方法:使用 nodemon
  1. 安装:

    bash 复制代码
    npm install -g nodemon
  2. 启动:

    bash 复制代码
    nodemon app.js

7. 在 Express 中如何实现实时通讯,如 SSE 服务端事件推送?

示例:SSE
javascript 复制代码
app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  let counter = 0;
  const interval = setInterval(() => {
    res.write(`data: ${counter++}\n\n`);
  }, 1000);

  req.on('close', () => clearInterval(interval));
});

8. Express 中如何处理异步请求和避免回调地狱?

使用 async/await
javascript 复制代码
app.get('/data', async (req, res, next) => {
  try {
    const data = await fetchData(); // 模拟异步操作
    res.send(data);
  } catch (error) {
    next(error);
  }
});
使用 Promise
javascript 复制代码
app.get('/data', (req, res, next) => {
  fetchData()
    .then((data) => res.send(data))
    .catch(next);
});
错误捕获
  • 结合全局错误处理中间件,避免繁琐的错误处理。

  • 示例:

    javascript 复制代码
    app.use((err, req, res, next) => {
      res.status(500).send({ error: err.message });
    });

以上是对问题的详细解答及代码示例,适用于实际开发中的多种场景。

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax