在 Dart 编程中,异步错误的处理机制是什么?请说明 try-catch 在异步场景下的正确使用方式,并比较不同异步原语(如 Future、async/await)中的错误捕获差异。
考察说明
考查候选人对 Dart 异步错误处理与 try-catch 在异步环境中应用的理解。
回答思路
- 【回答框架 1】Dart 异步错误处理核心在于 Future 的错误通道,try-catch 只能捕获同步异常和 await 表达式中 Future 的错误。未捕获的异步错误会进入 Zone 的错误处理器,可通过 runZonedGuarded 捕获全局未处理异常。
- 【回答框架 2】Future 的错误通过 .then 的 onError 回调或 .catchError 处理,而 async/await 中 try-catch 能捕获 await 的 Future 错误,但若未等待(不 await)Future,其错误不能被 try-catch 捕获,需使用 .catchError 或统一处理。
- 【回答框架 3】对于多个异步任务的错误处理,应使用 Future.wait 的 eagerError 参数或逐任务捕获;避免未处理的 Future 错误导致程序静默失败。另外,try-catch 无法捕获纯异步回调中的异常,如 Timer 或事件回调,需在回调内处理。
- 【回答框架 4】在代码中建议统一异常类型,使用 on 子句区分处理不同类型异常,并确保资源释放(如流、数据库连接),可配合 finally 使用。对于可重试或降级场景,可捕获后返回默认值,但需避免吞掉关键错误。
- 【关键点 1】try-catch 不能捕获未 await 的 Future 错误,必须 await 或显式使用 .catchError。
- 【关键点 2】Future 的错误传播沿异步链,若没有处理则进入 Zone,可通过 runZonedGuarded 全局捕获。
- 【关键点 3】async/await 中 try-catch 可以捕获 await 表达式中抛出的异常,但不能捕获其他异步函数内部未传播的异常。
- 【关键点 4】使用 .catchError 时注意返回类型匹配,避免因返回 Future 导致类型错误。
- 【关键点 5】对于并发异步任务,可使用 Future.wait 并提供 eagerError 参数,或逐个添加错误处理。
- 【易错点 1】直接抛出异常但不 await,导致错误未被捕获而静默失败。
- 【易错点 2】在 catchError 中返回 Future 时未注意类型兼容,导致类型错误。
- 【易错点 3】未能处理 Zone 中的未捕获异步错误,可能造成资源泄漏或不可预期行为。