singleWhere 方法
- bool test(
- T element
- {T orElse(
在该流中查找匹配 test
的单个元素。
返回一个未来,它完成于该流的单个元素,对于该元素,test
返回 true
。
如果在流完成之前没有找到此类元素,并且提供了 orElse
函数,则调用 orElse
的结果成为未来的值。如果 orElse
抛出异常,则返回的未来完成于该错误。
只能匹配一个元素。如果找到超过一个匹配元素,则无论是否传递了 orElse
,都会抛出错误。
如果该流在任何点发出错误,则返回的未来完成于该错误,并且取消订阅。
在流完成之前无法提供非错误结果。
类似于 lastWhere,但是如果在流中出现多个匹配元素,则会导致错误。
示例
var result = await Stream.fromIterable([1, 2, 3, 6, 9, 12])
.singleWhere((element) => element % 4 == 0, orElse: () => -1);
print(result); // 12
result = await Stream.fromIterable([2, 6, 8, 12, 24, 32])
.singleWhere((element) => element % 9 == 0, orElse: () => -1);
print(result); // -1
result = await Stream.fromIterable([2, 6, 8, 12, 24, 32])
.singleWhere((element) => element % 6 == 0, orElse: () => -1);
// Throws.
实现
Future<T> singleWhere(bool test(T element), {T orElse()?}) {
_Future<T> future = new _Future<T>();
late T result;
bool foundResult = false;
StreamSubscription<T> subscription =
this.listen(null, onError: future._completeError, onDone: () {
if (foundResult) {
future._complete(result);
return;
}
if (orElse != null) {
_runUserCode(orElse, future._complete, future._completeError);
return;
}
try {
throw IterableElementError.noElement();
} catch (e, s) {
_completeWithErrorCallback(future, e, s);
}
}, cancelOnError: true);
subscription.onData((T value) {
_runUserCode(() => test(value), (bool isMatch) {
if (isMatch) {
if (foundResult) {
try {
throw IterableElementError.tooMany();
} catch (e, s) {
_cancelAndErrorWithReplacement(subscription, future, e, s);
}
return;
}
foundResult = true;
result = value;
}
}, _cancelAndErrorClosure(subscription, future));
});
return future;
}