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

與篩選操作符一樣,如果來源 BlockingObservable 中沒有第一個元素,BlockingObservablefirst 方法將拋出 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

與篩選操作符一樣,如果來源 BlockingObservable 中沒有第一個元素,BlockingObservablefirst 方法將拋出 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 沒有發射任何項目(或如果它沒有發射它預期的第 n 個項目),則 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 將以「Sequence contains no elements.onError 通知終止。

single

single 操作符類似,只是它僅在來源 Observable 成功完成並發射一個項目(或一個符合謂詞的項目)後才發射其項目。如果它沒有發射任何此類項目或發射多個此類項目,則 single 將以 onError 通知(「Sequence contains no elements.」)終止。

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