First

仅发射 Observable 发射的第一个项目(或满足某些条件的第一个项目)

如果您只对 Observable 发射的第一个项目感兴趣,或者满足某些条件的第一个项目,您可以使用 First 运算符过滤 Observable。

在某些实现中,First 不是作为返回 Observable 的过滤运算符实现的,而是作为返回该项目的源 Observable 发射该项目的阻塞函数。在这些实现中,如果您想要过滤运算符,则可以使用 Take(1)ElementAt(0)

在某些实现中,也存在一个 Single 运算符。它的行为类似于 First,只是它会等待源 Observable 终止以确保它只发射单个项目(否则,它不会发射该项目,而是以错误终止)。您可以使用它来不仅从源 Observable 中获取第一个项目,而且还可以确保只有一个项目。

另见

特定于语言的信息

待定

在 RxGroovy 中,此过滤运算符实现为 firstfirstOrDefaulttakeFirst

有点令人困惑的是,还有一些名为 firstfirstOrDefaultBlockingObservable 运算符,它们会阻塞并返回项目,而不是立即返回 Observable。

还有其他几个运算符执行类似的功能。

过滤运算符

first

要过滤 Observable 以使其仅发射第一个发射,请使用不带参数的 first 运算符。

first

您还可以将谓词函数传递给 first,在这种情况下,它将生成一个 Observable,该 Observable 仅发射源 Observable 中谓词计算为 true 的第一个项目。

firstOrDefault

firstOrDefault 运算符类似于 first,但您可以向它传递一个默认项目,如果源 Observable 无法发射任何项目,它可以发射该默认项目

firstOrDefault

firstOrDefault 还有一个变体,您可以向它传递一个谓词函数,以便它的 Observable 会发射源 Observable 中谓词计算为 true 的第一个项目,或者如果源 Observable 发射的任何项目都没有通过谓词,则发射默认项目。

takeFirst

takeFirst 运算符的行为类似于 first,不同之处在于这些运算符在源 Observable 没有发射任何满足谓词的项目的时的行为。在这种情况下,first 将抛出 NoSuchElementException,而 takeFirst 将返回一个空的 Observable(一个调用 onCompleted 但从不调用 onNext 的 Observable)。

single

single 运算符类似于 first,但如果源 Observable 在成功完成之前没有发射正好一个项目,则会抛出 NoSuchElementException

single

single 还有一个版本,它接受一个谓词,并发射源 Observable 发射的唯一与该谓词匹配的项目,或者如果正好一个这样的项目不匹配,则通知异常。

singleOrDefault

firstOrDefault 一样,还有一个 singleOrDefault,它在源 Observable 为空时会发射一个默认项目,尽管如果源 Observable 发射了多个项目,它仍然会通知错误。

singleOrDefault

还有一个 singleOrDefault 版本,它接受一个谓词函数,并发射源 Observable 发射的唯一与该谓词匹配的项目(如果有);如果没有任何项目匹配,则发射默认项目;如果多个项目匹配,则发出错误通知。

firstfirstOrDefaultsinglesingleOrDefaulttakeFirst 默认情况下不会在任何特定的 Scheduler 上操作。

BlockingObservable 方法

BlockingObservable 方法不会将 Observable 转换为另一个经过过滤的 Observable,而是会跳出 Observable 级联,阻塞直到 Observable 发射所需的项目,然后返回该项目本身。

要将 Observable 转换为 BlockingObservable,以便您可以使用这些方法,您可以使用 Observable.toBlockingBlockingObservable.from 方法。

first

要从 BlockingObservable 中检索第一个发射,请使用不带参数的 first 方法。

first

您还可以将谓词函数传递给 first 方法以检索 BlockingObservable 中满足谓词的第一个发射。

firstOrDefault

与过滤运算符一样,BlockingObservablefirst 方法如果源 BlockingObservable 中没有第一个元素,将抛出 NoSuchElementException。要在这种情况下返回默认项目,请使用 firstOrDefault 方法。

firstOrDefault

并且,与 first 一样,还有一个 firstOrDefault 变体,它接受一个谓词函数作为参数,并返回源 BlockingObservable 中满足该谓词的第一个项目,或者如果未发射任何满足的项目,则返回一个默认项目。

single

single 运算符类似于 first,但如果源 Observable 在成功完成之前没有发射正好一个项目,则会抛出 NoSuchElementException

single

single 还有一个版本,它接受一个谓词,并返回源 Observable 发射的唯一与该谓词匹配的项目,或者如果正好一个这样的项目不匹配,则抛出异常。

singleOrDefault

firstOrDefault 一样,还有一个 singleOrDefault,它在源 Observable 为空时会返回一个默认项目,尽管如果源 Observable 发射了多个项目,它仍然会抛出错误。

singleOrDefault

还有一个 singleOrDefault 版本,它接受一个谓词函数,并返回源 Observable 发射的唯一与该谓词匹配的项目(如果有);如果没有任何项目匹配,则发射默认项目;如果多个项目匹配,则抛出错误。

next

next 运算符会阻塞直到 BlockingObservable 发射另一个项目,然后返回该项目。您可以重复调用此函数以从 BlockingObservable 中获取连续的项目,从而有效地以阻塞方式迭代其发射。

latest 运算符类似,但它不会阻塞以等待下一个发射的项目,而是立即返回最近发射的项目,并且只有在 Observable 尚未发射任何内容时才会阻塞。

mostRecent

mostRecent 运算符同样允许您迭代 BlockingObservable 的发射,但它的 Iterable 始终立即返回一个值:您提供的默认项目(如果 BlockingObservable 尚未发射任何项目),或者 BlockingObservable 已发射的最新项目。

在 RxJava 中,此过滤运算符实现为 firstfirstOrDefaulttakeFirst

有点令人困惑的是,还有一些名为 firstfirstOrDefaultBlockingObservable 运算符,它们会阻塞并返回项目,而不是立即返回 Observable。

还有其他几个运算符执行类似的功能。

过滤运算符

first

要过滤 Observable 以使其仅发射第一个发射,请使用不带参数的 first 运算符。

示例代码

Observable.just(1, 2, 3)
          .first()
          .subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });
Next: 1
Sequence complete.
first

您还可以将谓词函数传递给 first,在这种情况下,它将生成一个 Observable,该 Observable 仅发射源 Observable 中谓词计算为 true 的第一个项目。

firstOrDefault

firstOrDefault 运算符类似于 first,但您可以向它传递一个默认项目,如果源 Observable 无法发射任何项目,它可以发射该默认项目

firstOrDefault

firstOrDefault 还有一个变体,您可以向它传递一个谓词函数,以便它的 Observable 会发射源 Observable 中谓词计算为 true 的第一个项目,或者如果源 Observable 发射的任何项目都没有通过谓词,则发射默认项目。

takeFirst

takeFirst 运算符的行为类似于 first,不同之处在于这些运算符在源 Observable 没有发射任何满足谓词的项目的时的行为。在这种情况下,first 将抛出 NoSuchElementException,而 takeFirst 将返回一个空的 Observable(一个调用 onCompleted 但从不调用 onNext 的 Observable)。

single

single 运算符类似于 first,但如果源 Observable 在成功完成之前没有发射正好一个项目,则会抛出 NoSuchElementException

single

single 还有一个版本,它接受一个谓词,并发射源 Observable 发射的唯一与该谓词匹配的项目,或者如果正好一个这样的项目不匹配,则通知异常。

singleOrDefault

firstOrDefault 一样,还有一个 singleOrDefault,它在源 Observable 为空时会发射一个默认项目,尽管如果源 Observable 发射了多个项目,它仍然会通知错误。

singleOrDefault

还有一个 singleOrDefault 版本,它接受一个谓词函数,并发射源 Observable 发射的唯一与该谓词匹配的项目(如果有);如果没有任何项目匹配,则发射默认项目;如果多个项目匹配,则发出错误通知。

firstfirstOrDefaultsinglesingleOrDefaulttakeFirst 默认情况下不会在任何特定的 Scheduler 上操作。

BlockingObservable 方法

BlockingObservable 方法不会将 Observable 转换为另一个经过过滤的 Observable,而是会跳出 Observable 级联,阻塞直到 Observable 发射所需的项目,然后返回该项目本身。

要将 Observable 转换为 BlockingObservable,以便您可以使用这些方法,您可以使用 Observable.toBlockingBlockingObservable.from 方法。

first

要从 BlockingObservable 中检索第一个发射,请使用不带参数的 first 方法。

first

您还可以将谓词函数传递给 first 方法以检索 BlockingObservable 中满足谓词的第一个发射。

firstOrDefault

与过滤运算符一样,BlockingObservablefirst 方法如果源 BlockingObservable 中没有第一个元素,将抛出 NoSuchElementException。要在这种情况下返回默认项目,请使用 firstOrDefault 方法。

firstOrDefault

并且,与 first 一样,还有一个 firstOrDefault 变体,它接受一个谓词函数作为参数,并检索源 BlockingObservable 中满足该谓词的第一个项目,或者如果未发射任何满足的项目,则返回一个默认项目。

single

single 运算符类似于 first,但如果源 Observable 在成功完成之前没有发射正好一个项目,则会抛出 NoSuchElementException

single

single 还有一个版本,它接受一个谓词,并返回源 Observable 发射的唯一与该谓词匹配的项目,或者如果正好一个这样的项目不匹配,则抛出异常。

singleOrDefault

firstOrDefault 一样,还有一个 singleOrDefault,它在源 Observable 为空时会返回一个默认项目,尽管如果源 Observable 发射了多个项目,它仍然会抛出错误。

singleOrDefault

还有一个 singleOrDefault 版本,它接受一个谓词函数,并返回源 Observable 发射的唯一与该谓词匹配的项目(如果有);如果没有任何项目匹配,则发射默认项目;如果多个项目匹配,则抛出错误。

next

next 运算符会阻塞直到 BlockingObservable 发射另一个项目,然后返回该项目。您可以重复调用此函数以从 BlockingObservable 中获取连续的项目,从而有效地以阻塞方式迭代其发射。

latest 运算符类似,但它不会阻塞以等待下一个发射的项目,而是立即返回最近发射的项目,并且只有在 Observable 尚未发射任何内容时才会阻塞。

mostRecent

mostRecent 运算符同样允许您迭代 BlockingObservable 的发射,但它的 Iterable 始终立即返回一个值:您提供的默认项目(如果 BlockingObservable 尚未发射任何项目),或者 BlockingObservable 已发射的最新项目。

first

RxJS 实现 first 运算符。它可以选择接受一个谓词函数作为参数,在这种情况下,它不会发射源 Observable 的第一个项目,而是生成的 Observable 会发射源 Observable 中满足谓词的第一个项目。

谓词函数本身接受三个参数

  1. 源 Observable 中要过滤或不过滤的项目
  2. 此项目在源 Observable 序列中的从零开始的索引
  3. 源 Observable 对象

可选的第三个参数(名为 defaultValue)允许您选择一个项目,如果源 Observable 没有发射任何项目(或者没有发射它期望的第 nth 个项目),则 first 会发射该项目。

示例代码

var source = Rx.Observable.range(0, 10)
    .first(function (x, idx, obs) { return x % 2 === 1; });

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (err) { console.log('Error: ' + err); },
    function () { console.log('Completed'); });
Next: 1
Completed

如果源 Observable 没有发射任何项目(或没有发射任何与谓词匹配的项目),则 first 将以“序列不包含任何元素。onError 通知终止。

single

single 操作符类似,但它只在源 Observable 成功完成并发射一个项目(或一个匹配谓词的项目)后才发射一次该项目。如果它发射的项目数量不是一个(即零个或多个),single 将以 onError 通知(“序列不包含任何元素。”)终止。

find

find 操作符与 first 非常相似,只是谓词参数是必需的,并且当源 Observable 中没有项目匹配谓词时,它的行为会有所不同。first 在这种情况下会发送一个 onError 通知,而 find 则会发射一个 undefined 项目。

示例代码

var array = [1,2,3,4];

var source = Rx.Observable.fromArray(array)
    .find(function (x, i, obs) {
        return x === 5;
    });

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (err) { console.log('Error: ' + err); },
    function () { console.log('Completed'); });
Next: undefined
Completed
findIndex

findIndex 操作符与 find 类似,区别在于它不发射匹配谓词的项目(或 undefined),而是发射该项目在源 Observable 序列中的零基索引(或 -1)。

示例代码

var array = [1,2,3,4];

var source = Rx.Observable.fromArray(array)
    .findIndex(function (x, i, obs) {
        return x === 5;
    });

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (err) { console.log('Error: ' + err); },
    function () { console.log('Completed'); });
Next: -1
Completed

findfindIndexfirst 存在于以下每个发行版中

  • rx.all.js
  • rx.all.compat.js
  • rx.aggregates.js

它们每个都需要以下发行版之一

  • rx.js
  • rx.compat.js
  • rx.lite.js
  • rx.lite.compat.js