在 Dart 语言中,如何在保持生成值的同时在生成器函数中创建错误?
import 'dart:math' show Random;
main() {
sum20RandomNumbers().then((sum) {
print("Sum: $sum");
});
}
Future<double> sum20RandomNumbers() async {
var randomStream = generateRandomNumbers().handleError((error) {
print('Ignore large number: ${error}');
// How can I ignore error here?
});
int count = 0;
double sum = 0;
await for (var n in randomStream) {
print(n);
sum += n;
if (++count >= 20) // sum 20 numbers at most
break;
}
return sum;
}
Stream<double> generateRandomNumbers([int seed]) async* {
final random = Random(seed);
while (true) {
final nextDouble = random.nextDouble();
if (nextDouble > 0.8) {
throw Exception('$nextDouble');
// how can I keep generating next random numbers?
}
yield nextDouble;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码显示了sum20RandomNumbers()将 20 个随机数加起来的意图,但是在生成器函数中抛出异常后它将停止generateRandomNumbers()。抛出错误后如何保持生成器函数产生值?
对于sync*函数,您不能这样做。
Iterable报告错误的唯一方法是使Iterator的moveNext方法抛出。为此,sync*方法必须抛出。当sync*函数抛出时,它会终止函数体,这使得该函数体无法继续并产生更多值。
对于async*抛出的函数也会发生同样的事情,但是你也有一种不同的方式来发出错误。因为流可以作为流的一部分报告错误,所以可以发出错误并继续,但不能通过抛出.
Stream<double> generateRandomNumbers([int seed]) async* {
final random = Random(seed);
while (true) {
final nextDouble = random.nextDouble();
if (nextDouble > 0.8) {
yield* Future<double>.error(Exception('$nextDouble')).asStream();
continue;
}
yield nextDouble;
}
}
Run Code Online (Sandbox Code Playgroud)
诀窍是yield*包含错误的流。你可以用很多不同的方式做到这一点。
yield* Stream.error(theError);
Run Code Online (Sandbox Code Playgroud)
这个构造函数是在 Dart 2.5 中添加的,是最简单的方法。其他替代方案是:
yield* Future<double>.error(theError).asStream();
Run Code Online (Sandbox Code Playgroud)
或者
yield* () async* { throw theError; } ();
Run Code Online (Sandbox Code Playgroud)
或者
yield* (StreamController<double>()..addError(theError)..close()).stream;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
378 次 |
| 最近记录: |