async与await如何使用_处理异步操作有哪些技巧?

async/await 是 Promise 的语法糖,async 函数必返回 Promise 并自动包装返回值,await 只能在 async 函数中使用且仅暂停当前函数,多个独立请求应优先用 Promise.all 并行,错误处理必须用 try/catch 包裹每个 await。

async/await 不是魔法,它只是 Promise 的语法糖——用对了清爽如水,用错了照样掉坑里。

async 函数必须返回 Promise,但你可能没意识到它“自动包装”了返回值

声明一个 async 函数,哪怕里面全是同步代码,调用它也一定返回一个 Promise

async function getValue() {
  return 42;
}
console.log(getValue()); // Promise {: 42}

这意味着:
• 直接调用 getValue() 得到的是 Promise,不是 42
• 想拿到真实值,必须 await getValue()(在 async 函数内)或 getValue().then(...)(外部);
• 如果函数里 throw 错误,等价于返回 Promise.reject(...),所以一定要配 try/catch

await 只能用在 async 函数里,且只“暂停当前函数”,不卡主线程

常见错误:在普通函数或事件回调里直接写 await fetch(...) → 报错 SyntaxError: await is only valid in async function

  • ✅ 正确姿势:把逻辑包进 async 函数,再调用它
  • ❌ 错误姿势:button.addEventListener('click', () => { const data = await api(); })
  • ⚠️ 注意:await 后面如果不是 Promise,JS 会自动用 Promise.resolve(...) 包一层,比如 await 123 是合法的,但毫无异步意义

多个独立请求别傻傻串行 await,用 Promise.all 并行提速

连续写两个 await 就是串行执行,总耗时 ≈ 两请求之和;而它们彼此无关时,完全可并发发起:

// ❌ 串行:慢
const user = await fetchUser();
const posts = await fetchPosts(); // 等 user 完了才发 posts 请求

// ✅ 并行:快
const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);

关键点:
Promise.all 返回的仍是 Promise,所以可以 await
• 任一失败会导致整个 Promise.all reject,如需容错,可用 Promise.allSettled
• 别在 forEach 里 await —— 它不会等待,只是“发出去就不管了”,结果不可控。

错误处理不是可选项,try/catch 必须包裹每个 await 表达式

fetch 失败、JSON 解析出错、后端返回 500……这些都会让 await 抛出异常。不捕获?页面白屏或控制台红字静默崩溃。

async function loadData() {
  try {
    const res = await fetch('/api/profile');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error('加载失败:', err.message);
    // 这里可以 fallback 数据、上报错误、提示用户
    return null;
  }
}

补充提醒:
• 不要用 .catch() 链在 await 后面(语法错误);
finally 块适合放清理逻辑(如关闭 loading 状态),无论成功失败都执行;
• 在 React/Vue 组件中触发异步操作,还要防组件卸载后更新已销毁 state 的内存泄漏问题。

真正难的从来不是写对 async/await,而是判断哪些该串行、哪些该并行、哪些该降级、哪些该重试——语法只是表,逻辑才是里。