Realm.firstFirstAsync()。asObservable()不能始终与RxJava.switchIfEmpty一起使用

时间:2016-06-11 15:46:25

标签: realm rx-java

我正在尝试创建从领域读取对象的函数,如果找不到该对象,则发出一个空的observable。下面的代码在某种程度上起作用,因为我可以使用调试器将其停止并看到它点击Observable.empty()

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()
        }
}

但是当我尝试在Observable上使用switchIfEmpty时,如果在域中找不到代码,则代码永远不会发出defaultPlayer

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

奇怪的是,如果我更新原始方法以在first()之前加入flatMap

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陷入困境,所以我可能会做一些愚蠢的事情。

编辑:我创建了一个示例项目,突出了我看到的问题 - https://github.com/donaldlittlepie/realm-async-issue

1 个答案:

答案 0 :(得分:0)

由于我不完全理解的原因。如果您将take(1)移到正上方 flatMap并且在filter以下,它应该正常工作:

   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链。