2016-06-11 3 views
1

レルムからオブジェクトを読み取り、オブジェクトが見つからない場合は空のオブザーバブルを発行する関数を作成しようとしています。Realm.firstFirstAsync()。asObservable()が一貫してRxJava.switchIfEmptyを使用していません

fun readFromRealm(id: String): Observable<Player> { 
    return realm.where(Player::class.java) 
     .equalTo("id", id) 
     .findFirstAsync() 
     .asObservable<Player>() 
     .filter { it.isLoaded } 
     .flatMap { 
      if (it.isValid) 
       Observable.just(it) 
      else 
       Observable.empty() 
     } 
} 

しかし、私が観察上でコードをswitchIfEmptyを使用しようとすると、それが見つからない場合defaultPlayerを発することはありません:以下のコードは、私は、デバッガでそれを停止し、それがObservable.empty()を打つ見ることができるので、ある程度まで動作しますレルムで

return readFromRealm(playerId) 
     .take(1) 
     .map{ // do something with emitted observable } 
     .switchIfEmpty(Observable.just(defaultPlayer)) // use this if no player found 

奇妙なことは、私が前flatMapfirst()が含まれるように、元のメソッドを更新した場合ということです:

fun readFromRealm(id: String): Observable<Player> { 
    return realm.where(Player::class.java) 
     .equalTo("id", id) 
     .findFirstAsync() 
     .asObservable<Player>() 
     .filter { it.isLoaded } 
     .first() // add first 
     .flatMap { 
      if (it.isValid) 
       Observable.just(it) 
      else 
       Observable.empty() 
     } 
} 

すべてが期待通りに機能し始め、私は、このバージョンがあるため、自動更新を殺すだろうと考えていますフィルタの後に最初に出力された結果のみをキャプチャします。

私はまだRealmとRxをgrokしようとしているので、私はおそらく何かダムをやっているでしょう。

編集: - 私は完全に理解していない理由のためにhttps://github.com/donaldlittlepie/realm-async-issue

+0

はい。自動更新は引き続き機能しますが、あなたのtake(1)はイベントがチェーンをさらに伝播するのを止めます。 –

+0

'findAllAsync()'を使ってみて、 'map()'を使って 'if(count> 0){return results.get(0); } else {nullを返します。 } 'しかし、私はRxでそれを書く方法を知らないので、これはコメントです。 – EpicPandaForce

答えて

0

私は私が見ている問題を浮き彫りにサンプルプロジェクトを作成しました。あなただけ flatMapの上や下にfiltertake(1)を移動した場合には、正常に動作する必要があります

realm.where(Dog.class) 
      .equalTo("id", 0L) 
      .findFirstAsync() 
      .asObservable() 
      .cast(Dog.class) 
      .filter(new Func1<RealmObject, Boolean>() { 
       @Override 
       public Boolean call(RealmObject realmObject) { 
        return realmObject.isLoaded(); 
       } 
      }) 
      .take(1) // <== here 
      .flatMap(new Func1<Dog, Observable<Dog>>() { 
       @Override 
       public Observable<Dog> call(Dog realmObject) { 
        if (realmObject.isValid()) { 
         return Observable.just(realmObject); 
        } else { 
         return Observable.empty(); 
        } 
       } 
      }) 
      .map(new Func1<Dog, Dog>() { 
       @Override 
       public Dog call(Dog dog) { 
        dog.setName("mapped " + dog.getName()); 
        return dog; 
       } 
      }) 
      .switchIfEmpty(Observable.just(createDefaultDog())) 
      .subscribe(new Action1<Dog>() { 
       @Override 
       public void call(Dog dog) { 
        textView.setText(dog.getName()); 
       } 
      }, new Action1<Throwable>() { 
       @Override 
       public void call(Throwable throwable) { 
        textView.setText(throwable.toString()); 

       } 
      }); 

私の最高の推測では、前に、flatMapが繰り返し呼び出されたことで、Observable.empty()複数回を返します。おそらくそれはObservableチェーンに予期しない方法で影響を与えるでしょう。

+0

私はこのサンプルの動作に同意します。私は実際には、すべてが並んでいることを確認するために、領域から画像を取り出すことも試みました。 – donaldlittlpie

+0

私はhttps://github.com/donaldlittlepie/realm-async-issueに表示されている問題をハイライトするサンプルプロジェクトを作成しました。 'MainActivity.java'には、私の領域結果に基づいて更新されるべき2つのテキストビューがあります。 'findEmptyInRealm'メソッドは決してサブスクリプションに到達しません。 – donaldlittlpie

+0

プロジェクトをありがとう。私の所見で回答を更新しました –

関連する問題