async函数执行失败时不会自动返回默认值,必须主动try/catch捕获异常后显式return fallback值,否则返回rejected promise;调用侧也可用.catch()等统一兜底,但需注意类型一致性和资源清理。

async 函数执行失败时不会自动返回默认值,必须主动处理错误并显式返回 fallback 值。
关键在于:async 函数一旦抛出异常(如 throw、await Promise.reject() 或未捕获的错误),就会让整个函数返回一个 rejected 状态的 Promise,而不是静默降级。要返回默认值,就得拦截这个异常。
用 try/catch 捕获异常后 return 默认值
这是最直接、最可控的方式。在 async 函数内部包裹可能出错的逻辑,catch 中不 re-throw,而是返回你想要的默认结果。
- try 块中写正常 await 逻辑
- catch 块里做日志、监控或补偿,然后 return 一个符合类型预期的值(比如空字符串、null、0、空数组等)
- 注意保持返回值类型一致(尤其在 TypeScript 或 ArkTS 中)
async function fetchUser(): Promise<string> {
try {
const res = await fetch('/api/user');
if (!res.ok) throw new Error('HTTP error');
return await res.text();
} catch (err) {
console.warn('获取用户失败,返回默认值');
return 'guest'; // 显式 fallback,类型仍为 string
}
}</string>
不要依赖 await 自动兜底
await someAsync() 遇到 rejected Promise 会立即中断后续代码,并把异常向上冒泡。它不会像 dict.get(key, default) 那样“安静地”返回 fallback。
-
await Promise.reject()→ 抛异常 → 必须 try/catch 或.catch()处理 -
await 123或await Promise.resolve(123)→ 正常解析为 123
在调用侧统一兜底(适用于无法修改原函数时)
如果不能改写 async 函数本身,可在调用处用 .catch() 或 handle(Java)、exceptionally(CompletableFuture)等方式提供默认值:
-
JavaScript:
fetchUser().catch(() => 'guest')
-
Java CompletableFuture:
future.exceptionally(ex -> "默认值")
-
Python asyncio:
try: result = await asyncio.wait_for(task, timeout=5) except asyncio.TimeoutError: result = "默认值"
避免常见陷阱
- 不要在 catch 里只
console.error而不 return —— 这会导致函数返回Promise<undefined></undefined>,可能破坏类型契约 - 不要重复 await 已被取消的协程(Python)或已 reject 的 Promise(JS)——可能引发运行时错误
- 不要用装饰器“封装”默认值逻辑,容易掩盖取消状态或干扰资源清理
本质上,返回默认值不是语言特性,而是业务决策。该在哪一层兜底(函数内 / 调用方 / 统一中间件),取决于错误语义和系统设计。











