Implementation
Future<E> waitFor<E>({
required Duration duration,
bool Function(E)? filter,
FutureOr<E> Function()? onTimeout,
}) async {
final completer = Completer<E>();
final cancelFunc = on<E>(
(event) {
if (!completer.isCompleted) {
completer.complete(event);
}
},
filter: filter,
);
try {
// wait to complete with timeout
return await completer.future.timeout(
duration,
onTimeout: onTimeout ?? () => throw TimeoutException(),
);
// do not catch exceptions and pass it up
} finally {
// always clean-up listener
await cancelFunc.call();
}
}