我正在设计一个 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
函数。
看,我可以解释你的预期结果和实际结果的差异。
当你将一个函数标记为
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
现在,想想它是如何给出预期结果的!如果没有收到请回复。