处理标记为异步的 void Dart 函数中的错误

问题描述 投票:0回答:1

我正在设计一个 api,希望处理用户错误标记

void
函数
async
的情况。

简化代码如下:

 void test(void Function() run) {
  try {
    for (var i = 0; i < 3; i++) {
      print(i);
      run();
    }
  } catch (e) {
    print(e);
  } finally {
    print('In finally block.');
  }
}

void main(List<String> args) {
  test(() async {  // <-------------- Marked async by mistake.
    throw 'In void function erroneously marked async';
  });
}

如果该函数标记为

async
,则程序输出符合预期,错误为 抛出、捕获、处理,然后执行
finally
块:

$ dart main.dart
0
In void function erroneously marked async
In finally block.

但是,如果该函数被标记为

async
,则控制台输出为:

$ dart main.dart 
0
1
2
3
In finally block.
Unhandled exception:
In void function erroneously marked async
#0      main.<anonymous closure> (file:///main.dart:16:5)
#1      test (file:///main.dart:5:10)
#2      main (file:///main.dart:15:3)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-  patch/isolate_patch.dart:294:33)
#4      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)

发生什么事了?我尝试了调试器,程序进入

run()
,然后循环继续。 它看起来像是一个未等待的未来错误,但我不知道如何捕获和处理它,因为无法等待
void
函数。

dart error-handling async-await try-catch void
1个回答
0
投票

看,我可以解释你的预期结果和实际结果的差异。

当你将一个函数标记为

async
时,这意味着该函数返回一种称为
Future
的特殊类型的对象。
Future
表示可能完成或可能未完成的潜在
asynchronous
操作。当您调用
async
函数时,它会立即返回,并且函数内部的工作发生在
background
中。这就是 Dart 能够执行的原因
asynchronous programming

在您的

test
函数中,您将另一个名为 run 的函数作为参数。当您将 run 标记为
async
时,这意味着它正在返回
Future<void>
,并且当您调用它
without await
时,函数执行不会暂停以等待 run 函数完成。相反,它会立即循环。
这就是为什么您看到循环正在运行而无需等待 run 函数完成。它是并发运行的,并且它抛出的 

continues

不会被

exceptions
块捕获,因为
try/catch
块在 run 函数完成之前就已经完成了。
下面的代码将得出您预期的答案:

try/catch

现在,想想它是如何给出预期结果的!如果没有收到请回复。

© www.soinside.com 2019 - 2024. All rights reserved.