Node.js 18 异步编程:Promise 与 async/await

在 Node.js 中,异步编程是核心能力,尤其在高并发 I/O 场景下。Promise 和 async/await 是处理异步操作的现代方案,可避免回调地狱(Callback Hell),提升代码可读性和可维护性。

1. Promise 基础

Promise 表示一个异步操作的最终完成(或失败)及其结果值。它有三种状态:

  • Pending:初始状态
  • Fulfilled:操作成功完成
  • Rejected:操作失败

基本用法

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = Math.random() > 0.5; // 模拟随机成功/失败
      success ? resolve("数据获取成功") : reject("请求超时");
    }, 1000);
  });
};

// 使用 then/catch 处理结果
fetchData()
  .then(result => console.log(result))
  .catch(error => console.error(error));

链式调用

fetchData()
  .then(data => data.toUpperCase())
  .then(processedData => console.log(processedData))
  .catch(error => console.error("处理失败:", error));

2. async/await 语法糖

async/await 基于 Promise,用同步写法处理异步操作:

  • async 声明异步函数
  • await 暂停执行直到 Promise 完成

基本用法

async function processAsync() {
  try {
    const result = await fetchData(); // 等待 Promise 完成
    console.log("处理结果:", result);
  } catch (error) {
    console.error("捕获错误:", error);
  }
}

processAsync();

3. 关键对比
特性 Promise async/await
错误处理 .catch() 或链式调用 try/catch
可读性 链式调用可能嵌套 线性同步风格,更易理解
调试 错误栈可能复杂 错误栈更清晰
兼容性 ES6+ 支持 需要 Node.js 7.6+ 或转译工具
4. 实际应用示例

并行请求优化

// 使用 Promise.all 并行处理
async function fetchMultiple() {
  const [user, posts] = await Promise.all([
    fetch('/api/user'),
    fetch('/api/posts')
  ]);
  console.log("用户数据:", user, "文章数据:", posts);
}

错误优先实践

async function safeOperation() {
  const result = await fetchData().catch(e => {
    console.warn("降级处理:", e);
    return "默认值";
  });
  console.log("最终结果:", result);
}

5. Node.js 18 增强特性
  • Top-level await:在模块顶层直接使用 await(需启用 ES Module)
  • Promise 组合器
    // 竞态场景:取最先完成的结果
    const winner = await Promise.race([fetchA(), fetchB()]);
    
    // 全部完成(无论成功失败)
    const allSettled = await Promise.allSettled([task1(), task2()]);
    

最佳实践
  1. 优先用 async/await 替代深层 Promise 链
  2. 始终用 try/catch 包裹可能失败的异步操作
  3. I/O 密集型操作使用 Promise.all 并行化
  4. 避免在循环中无阻塞地使用 await(需评估并发需求)

在 Node.js 18 中,这两种方案已深度集成。例如,fs.promises API 直接返回 Promise,而 http 模块可通过 util.promisify 转换为 Promise 接口,实现无缝协作。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐