引入
文件读取、网络请求和数据库操作都可能需要等待。如果让进程同步阻塞在每个耗时操作上,并发能力会下降。Node.js 通常使用异步 API,让 JavaScript 线程在等待期间继续处理其他任务。
正文
Promise 和 async/await
import { readFile } from 'node:fs/promises';
async function loadConfig() {
try {
const content = await readFile('./config.json', 'utf8');
return JSON.parse(content);
} catch (error) {
throw new Error('读取配置失败', { cause: error });
}
}async 函数始终返回 Promise,await 只会暂停当前异步函数,不会阻塞整个 Node.js 进程。
串行与并行
有依赖关系时串行执行:
const user = await loadUser();
const orders = await loadOrders(user.id);互不依赖时可以并行执行:
const [users, products] = await Promise.all([
loadUsers(),
loadProducts()
]);Promise.all 中任意任务失败,整体就会失败。如果需要收集每个任务的结果,可以使用 Promise.allSettled。
错误处理
await放在try/catch中,才能捕获对应 Promise 的异常。- 不要忽略异步函数返回的 Promise,否则错误可能变成未处理拒绝。
- 网络请求、文件和用户输入都应考虑失败、超时和无效数据。
- 不要使用同步文件 API 处理高并发请求中的大文件。
事件循环的边界
Node.js 可以高效处理大量 I/O 等待,但 CPU 密集型计算仍会占用主线程。大计算、无限循环或同步大文件操作会阻塞其他请求,必要时应拆分任务或使用 Worker Threads 等方案。
引出
异步代码的关键不是把所有函数都写成 async,而是明确哪些任务可以并行、哪些错误必须处理,以及什么时候需要超时和取消。接下来可以把异步逻辑放进 NodejsHTTP服务。