【问题标题】:Future.wait() not catching exceptions (Dart)Future.wait() 没有捕获异常 (Dart)
【发布时间】:2019-11-18 10:39:42
【问题描述】:

在我的 Flutter 应用程序中,我想同时进行多个网络调用,然后在它们都完成后执行一些操作。为此,我使用Future.wait(),它可以满足我的需求。然而,当调用失败时,它会抛出一个异常,该异常不会在异常处理程序中被捕获(即未捕获的异常)。

当我单独执行await _fetchSomeData()(在Future.wait() 之外)时,异常处理程序会按预期调用异常。

  Future<bool> someMethod() async {

    try {
      var results = await Future.wait([
        _fetchSomeData(),
        _fetchSomeOtherData()
      ]);
      //do some stuf when both have finished...
      return true;
    }
    on Exception catch(e) {
      //does not get triggered somehow...
      _handleError(e);
      return false;
    }
  } 

在使用Future.wait() 时,我需要做什么才能捕获异常?

更新:

我已经缩小了问题的范围。事实证明,如果您在 Future.wait() 调用的方法中使用另一个 await 语句,则会导致问题。举个例子:

  void _futureWaitTest() async {

    try {
      //await _someMethod(); //using this does not cause an uncaught exception, but the line below does
      await Future.wait([ _someMethod(), ]);
    }
    on Exception catch(e) {
      print(e);
    } 
  }

  Future<bool> _someMethod() async {
    await Future.delayed(Duration(seconds: 0), () => print('wait')); //removing this prevents the uncaught exception
    throw Exception('some exception');
  }

因此,如果您从 _someMethod() 中删除 await 行,或者您只是在 Future.wait() 之外调用 _someMethod() 将防止未捕获的异常。这当然是最不幸的,我需要等待一个 http 调用...... Dart 中的一些错误?

我启用了未捕获异常断点。如果我关闭它,问题似乎就消失了。可能是调试器的问题。我正在使用 Visual Studio Code 和最新的 Flutter。

【问题讨论】:

  • 也许您正在其中一种方法(_fetchSomeData 或 _fetchSomeOtherData)中处理这些异常,并且没有在这些方法之上重新抛出要处理的异常。
  • 这个答案可能会有所帮助 - stackoverflow.com/a/16022953/4465386
  • try { var result = await Future.wait([ Future.delayed(Duration(seconds: 1), () =&gt; 'first'), Future.delayed(Duration(seconds: 2), () =&gt; 'second'), Future.delayed(Duration(seconds: 3), () =&gt; throw Exception('bad things happened')), ]); print('result: $result'); } on Exception catch(e) { print('error: [$e]'); } 你在日志上看到了什么?
  • 是的,我已经缩小了问题的范围。我正在更新我的帖子。
  • 请查看我的开场帖中的更新信息。你现在能重现这个问题吗?

标签: exception flutter dart


【解决方案1】:

我认为Future.wait() 命名有点误导您。 Future.wait() 返回另一个未来,当它成功完成时,每个未来将返回一个 List 元素。

现在Future.wait() 仍然是一个未来。您可以通过两种方式处理它:

  1. awaittry catch 结合使用。
  2. 使用onError 回调。

会是这样的

Future.wait([futureOne, futureTwo])
.then((listOfValues) {
    print("ALL GOOD")
 }, 
 onError: (error) { print("Something is not ok") }

【讨论】:

  • 我已经尝试了这两种方法,您可以在我的示例中看到我使用 try catch。
  • @Janneman 我没有看到你在哪里使用了onError 回调。
  • 我也尝试过,但我在示例中使用了 try/catch 方法。我刚刚更新了我的初始帖子,其中包含更多信息。
【解决方案2】:

在使用 Future.wait() 时我需要做什么才能捕获异常?

当我使用与您相同的代码时,我发现Future.wait() 中使用的每个过程中的代码必须用try/catch 包装,并且catch 必须返回Future.error()。另外eagerError 必须设置为true

try {
  await Future.wait([proc1, ...], eagerError: true);
} on catch(e) {
  print('error: $e')
}

/// Proc 1
Future<void> proc1() async {
  try {
    final result = await func();
  } on SomeException catch(e) {
    return Future.error('proc 1 error: $');
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 2021-06-20
    • 2013-03-24
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多