dart - Dart:如何“等待”Future.wait 的清理?
问题描述
以下面的代码为例,可以推断出 Future.wait 的 cleanUp 在调用时没有“等待” await Future.wait
。
如果我不包括语句“1 - 必须在此处等待”,则测试将不会通过。
import 'package:test/test.dart';
void main() {
test('test Future.wait', () async {
final waitSeconds = 5;
DateTime slowOkExecutedTime;
DateTime slowErrorExecutedTime;
DateTime cleanUpExecutedTime;
DateTime slowCleanUpExecutedTime;
Future slowOk() {
return Future.delayed(Duration(seconds: waitSeconds), () {
slowOkExecutedTime = DateTime.now();
return true;
});
}
Future slowError() {
return Future.delayed(Duration(seconds: waitSeconds), () {
slowErrorExecutedTime = DateTime.now();
throw Exception("SlowError");
});
}
Future slowCleanUp() {
return Future.delayed(Duration(seconds: waitSeconds), () {
slowCleanUpExecutedTime = DateTime.now();
return true;
});
}
try {
await Future.wait([
Future.microtask(() => slowOk()),
Future.microtask(() => slowError()),
], cleanUp: (value) async {
cleanUpExecutedTime = DateTime.now();
expect(value, true);
expect(slowOkExecutedTime != null, true);
expect(
cleanUpExecutedTime.isAfter(slowOkExecutedTime),
true,
);
return await slowCleanUp();
});
fail("Should have thrown SlowError");
} catch (error) {
expect(error.toString().contains("SlowError"), true);
}
expect(slowOkExecutedTime != null, true);
expect(slowErrorExecutedTime != null, true);
expect(cleanUpExecutedTime != null, true);
expect(slowCleanUpExecutedTime != null, false);
// 1 - must wait here
await Future.delayed(
Duration(milliseconds: waitSeconds * 1000 + 10), () {});
expect(slowCleanUpExecutedTime != null, true);
expect(
cleanUpExecutedTime.isAfter(slowOkExecutedTime),
true,
);
expect(
cleanUpExecutedTime.isAfter(slowErrorExecutedTime),
true,
);
expect(
slowCleanUpExecutedTime.isAfter(cleanUpExecutedTime),
true,
);
final now = DateTime.now();
print(
'Clean up executed time: ${slowCleanUpExecutedTime.toIso8601String()}');
print(' Now: ${now.toIso8601String()}');
expect(
now.isAfter(slowCleanUpExecutedTime),
true,
);
});
}
我只想在 Future.wait 返回之前等待 cleanUp 运行。
有没有推荐的方法来解决这个问题,也许使用另一种方法?
解决方案
传递给的方法onCatch
将被同步调用并且不期望返回值。如果您需要在该方法中等待或返回内容,您可能需要重新评估是否有其他方法可以做您正在做的事情。
如果您绝对需要让外部上下文等待异步onCatch
方法,则需要将期货提升到外部上下文,以便您可以单独等待它们。
final cleanUpFutures = <Future>[];
try {
await Future.wait([
Future.microtask(() => slowOk()),
Future.microtask(() => slowError()),
], cleanUp: (value) {
cleanUpFutures.push(() async {
cleanUpExecutedTime = DateTime.now();
expect(value, true);
expect(slowOkExecutedTime != null, true);
expect(
cleanUpExecutedTime.isAfter(slowOkExecutedTime),
true,
);
await slowCleanUp());
}());
});
fail("Should have thrown SlowError");
} catch (error) {
expect(error.toString().contains("SlowError"), true);
}
await Future.wait(cleanUpFutures);
...
推荐阅读
- batch-file - 用今天的日期重命名文件名中具有 & 的文件
- c# - C#如何将所有文件从服务器下载到本地文件夹
- regex - 匹配匹配符号之间或行尾之间的行中的所有字符
- angular - 使用数据存储和主题行为时更新回调(Angular 7)
- haskell - 查找一系列数字的 Collatz 序列
- android - 找不到符号:数据绑定组件
- apache-spark - spark流集群可以用来缓冲数据吗?
- .net - AWS弹性搜索服务返回403响应与.NET HttpClient-http请求标头中的错误大小写
- c - C 程序中的功能块架构
- c# - 如何获取经过身份验证的用户的访问令牌以进行授权的资源 api 调用?