亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 Single 應用于 ObservableSource 而不是過度閱讀

將 Single 應用于 ObservableSource 而不是過度閱讀

波斯汪 2023-02-23 10:53:22
總的來說,我對 RX 很陌生,尤其是 rxjava,請原諒我的錯誤。此操作依賴于兩個異步操作。第一個使用過濾器函數嘗試從異步 Observable 返回的列表中獲取單個實體。第二個是與設備通信并生成狀態更新的 Observable 的異步操作。我想獲取從過濾器函數創建的 Single,將其應用于pairReader(...),并訂閱其 Observable 以獲取更新。我可以讓它如圖所示工作,但前提是我包含注釋take(1),否則我會得到一個異常,因為鏈試圖從 Single 中提取另一個值。  Observable<DeviceCredential> getCredentials() {    return deviceCredentialService()            .getCredentials()            .flatMapIterable(event -> event.getData());  }  Single<Organization> getOrgFromCreds(String orgid) {    return getCredentials()      // A device is logically constrained to only have a single cred per org      .map(DeviceCredential::getOrganization)      .filter(org -> org.getId().equals(orgid))      .take(1)  // Without this I get an exception      .singleOrError();  }  Function<Organization, Observable<Reader.EnrollmentState>> pairReader(String name) {    return org -> readerService().pair(name, org);  }getOrgFromCreds(orgid)  .flatMapObservable(pairReader(readerid))  .subscribe(state -> {     switch(state) {       case BEGUN:         LOG.d(TAG, "Pairing begun");         break;       case PAIRED:         LOG.d(TAG, "Pairing success");         callback.success();         break;       case NOTIFIED_SERVER:         LOG.d(TAG, "Pairing server notified");         break;     }},     error -> {       Crashlytics.logException(error);       callback.error(error.getLocalizedMessage());     });
查看完整描述

3 回答

?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

如果我沒看錯,您需要使用之前檢索到的異步數據執行一些操作。因此,您可以使用.zip()運算符。這是一個例子:

Observable.zip(
                getOrgFromCreds().toObservable(),
                getCredentials(),
                (first, second) -> /*create output object here*/)
                .subscribe(
                        (n) -> /*do onNext*/,
                        (e) -> /*do onError*/
                );

請注意,該.zip()運算符將等待兩個流的發射,然后它將使用您在“此處創建輸出對象”中提供的函數創建外部發射。如果您不想等待這兩個項目 - 您可以使用.combineLatest()。


查看完整回答
反對 回復 2023-02-23
?
SMILET

TA貢獻1796條經驗 獲得超4個贊

如果源流發出不止一項,singleOrError()則應該發出錯誤。文檔

對于您的情況,請使用first()firstOrError()代替。

  Single<Organization> getOrgFromCreds(String orgid) { 
     return getCredentials()
      .map(DeviceCredential::getOrganization)
      .filter(org -> org.getId().equals(orgid))
      .firstOrError();
  }


查看完整回答
反對 回復 2023-02-23
?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

這里的問題原來是 API 的設計方式很奇怪(不幸的是,文檔非常糟糕)。我不明白為什么我得到重復項,并認為我使用flatMapIterable不正確。


該deviceCredentialService.getCredentials()調用實際創建的是一個可觀察對象,它發出DataEvent對象,這些對象是對結果列表的簡單包裝,并帶有結果來源的標志。


API 設計者希望允許用戶使用本地緩存的數據立即填充 UI,同時執行對 REST API 的較長請求。該DataEvent.from屬性是一個枚舉,用于標記來自本地設備緩存或來自遠程 API 調用的來源。


我解決這個問題的方法是簡單地忽略來自本地緩存的結果,只從 API 發出結果:


  Observable<DeviceCredential> getCredentials() {

    return deviceCredentialService()

      .getCredentials()

      // Only get creds from network

      .filter(e -> e.getFrom() == SyncedDataSourceObservableFactory.From.SOURCE)

      .flatMapIterable(e -> e.getData());

  }


  Single<Organization> getOrgFromCreds(String orgid) {

    return getCredentials()

      // A device is logically constrained to only have a single cred per org

      .map(DeviceCredential::getOrganization)

      .filter(org -> org.getId().equals(orgid))

      .singleOrError();

  }

然后計劃是使用記憶化緩存實體,使實施應用程序能夠訪問緩存失效。由于提供的接口不允許抑制 API 調用,因此如果應用程序感覺它是新鮮的,則無法僅使用緩存。


查看完整回答
反對 回復 2023-02-23
  • 3 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號