Android Studio 3.1 RC 2
kotlin 1.2.30
Java中fetchMessage的签名
Single<Response> fetchMessage(final String Id);
kotlin代码
fun translate(Id: String): Completable {
return repository.fetchMessage(Id)
.flatMap {
Single.fromCallable<State>({
update(messageId, it, State.COMPLETED)
State.COMPLETED
})
}
.onErrorReturn({
update(Id, null, State.ERROR)
State.ERROR
})
.toCompletable()
}
我想在fetchMessage
之前运行的方法 fun insertMessage(Id: String): Completable {
return Completable.fromCallable {
insert(Id, State.IDLE)
}
}
我希望insertMessage e以某种方式在fetchMessage之前运行。我在考虑使用concatMap但不确定如何组合translate和insertMessage。这样insertMessage将首先运行,然后一旦完成,将运行translate。
非常感谢任何建议,
Update solution 1 using startWith(..):
通过将translate方法的返回值更改为Single。我这样做了:
fun translate(Id: String): Single<State> {
return repository.fetchMessage(Id)
.flatMap {
Single.fromCallable<State>({
update(messageId, it, State.COMPLETED)
State.COMPLETED
})
}
.onErrorReturn({
update(Id, null, State.ERROR)
State.ERROR
})
}
然后我可以有一个方法来执行以下insertMessage(..) - &gt;翻译(..):
translate(Id).toCompletable().startWith(insertMessage(id, State.IDLE))
这会是一个理想的解决方案吗?
Update solution 2 using concatWith(..):
我返回一个Observable并在链中调用toObservable()。
fun translate(Id: String): Observable<State> {
return repository.fetchMessage(Id)
.flatMap {
Single.fromCallable<State>({
update(messageId, it, State.COMPLETED)
State.COMPLETED
})
}
.onErrorReturn({
update(Id, null, State.ERROR)
State.ERROR
})
.toObservable()
}
我可以使用concatWith,因此序列将是insertMessage(..) - &gt;翻译(..):
translate(Id).toCompletable().concatWith(insertMessage(id, State.IDLE).toObservable())
.toCompletable()
这些是正确的解决方案吗?
答案 0 :(得分:5)
如果您有Completable
,则可以通过andThen
链接任何其他被动类型:
insertMessage("id")
.andThen(translate("id"))
答案 1 :(得分:2)
你的选择都有道理,但我建议你稍微清理一下。
首先,您需要清楚地了解每种情况下要使用的返回类型:Observable,Single或Completable。
定义如下:
在您的两种情况下,您都不需要返回任何数据,您只需知道操作是否成功。 Completable旨在处理这种情况。
所以我建议您:
UISpellDatabase.Instance.spells.Add(new UISpellInfo());
让您的代码更清晰的不错选择是使用Completable.fromAction代替Completable.fromCallable,因此您不需要返回任何内容。
然后,您可以使用任何选项,startWith或concatWith。两者都等到第一个observable完成后再运行第二个observable。我更喜欢使用concatWith,因为它以与编写它们相同的顺序运行函数。
最终我们得到了一个优雅的解决方案:
fun translate(Id: String): Completable {
return repository.fetchMessage(Id)
.flatMapCompletable {
Completable.fromAction {
update(messageId, it, State.COMPLETED)
}
}.doOnError {
update(Id, null, State.ERROR)
}
}
fun insertMessage(Id: String): Completable {
return Completable.fromCallable {
insert(Id, State.IDLE)
}
}
或
insertMessage(id).concatWith(translate(id))
有关concat的更多信息:http://reactivex.io/documentation/operators/concat.html
如果你很好奇,这里是rxJava库中函数的实现:
translate(id).startWith(insertMessage(id))
正如您所看到的,唯一的区别是订单。