firstWhere 方法

Future<T> firstWhere(
  1. bool test(
    1. T element
    ),
  2. {T orElse(
      )?}
    )

    查找此流中匹配 test 的第一个元素。

    返回一个 Future,它在找到此流的第一个使 test 返回 true 的元素时完成。

    如果在流完成之前没有找到此类元素,并且提供了 orElse 函数,则调用 orElse 的结果将成为 Future 的值。如果 orElse 抛出异常,返回的 Future 将以该错误完成。

    如果此流在接收第一个匹配元素之前发出错误,则返回的 Future 将以该错误完成,并且处理停止。

    在接收到第一个匹配元素或错误后停止监听此流。

    该方法在匹配谓词的第一个元素后内部取消其订阅。这意味着在调用此方法之后,单一订阅(非广播)流将被关闭,并且不能重用它。

    如果发生错误,或者在没有任何 orElse 函数提供的情况下此流在找不到匹配项时结束,返回的 Future 将以错误完成。

    示例

    var result = await Stream.fromIterable([1, 3, 4, 9, 12])
        .firstWhere((element) => element % 6 == 0, orElse: () => -1);
    print(result); // 12
    
    result = await Stream.fromIterable([1, 2, 3, 4, 5])
        .firstWhere((element) => element % 6 == 0, orElse: () => -1);
    print(result); // -1
    

    实现

    Future<T> firstWhere(bool test(T element), {T orElse()?}) {
      _Future<T> future = new _Future();
      StreamSubscription<T> subscription =
          this.listen(null, onError: future._completeError, onDone: () {
        if (orElse != null) {
          _runUserCode(orElse, future._complete, future._completeError);
          return;
        }
        try {
          // Sets stackTrace on error.
          throw IterableElementError.noElement();
        } catch (e, s) {
          _completeWithErrorCallback(future, e, s);
        }
      }, cancelOnError: true);
    
      subscription.onData((T value) {
        _runUserCode(() => test(value), (bool isMatch) {
          if (isMatch) {
            _cancelAndValue(subscription, future, value);
          }
        }, _cancelAndErrorClosure(subscription, future));
      });
      return future;
    }