使用杰克沃顿的Managing State with RxJava模式。
我将两个api调用组合在一起并行执行。
我如何发出成功"两者都完成后的项目?
请参阅以下代码中的评论。
谢谢!
主要通话功能:
Observable
.just(UpdatePicEvent(userId, file))
.compose(updatePic()) <-- Handles updating pic, emits models consumed by UI
.mergeWith(
Observable
.just(UpdateProfileEvent(..params...))
.compose(updateProfile()) <-- Handles updating other settings, emits models consumed by UI
)
// TODO Need to add something to emit a Success() model item when both actions above have completed
.subscribe(...pass models to UI...)
updatePic()
fun updatePic(): ObservableTransformer<UpdatePicEvent, ProfileSettingsModel> {
return ObservableTransformer {
it.flatMap {
api.uploadProfilePic(it.userId, it.pic)
.map { UpdatePicSuccessful(it) as ProfileSettingsModel }
.onErrorReturn { UpdatePicError(it) as ProfileSettingsModel }
.startWith(UpdatePicInProgress() as ProfileSettingsModel)
}
}
}
updateProfile()
fun updateProfile(): ObservableTransformer<UpdateProfileEvent, ProfileSettingsModel> {
return ObservableTransformer {
it.flatMap {
api
.updateUser(...params...)
.subscribeOn(Schedulers.io())
.map { UpdateProfileSuccessful(it) as ProfileSettingsModel }
.onErrorReturn { UpdateProfileError(it) as ProfileSettingsModel }
.observeOn(AndroidSchedulers.mainThread())
.startWith(UpdateProfileInProgress() as ProfileSettingsModel)
}
}
}
答案 0 :(得分:0)
您收到两个不同的ProfileSettingsModel
您需要合并。如果您不想在订阅者中执行此操作,则可以使用zip operator来实现您的链。
通过指定的函数将多个Observable的排放组合在一起,并根据此函数的结果为每个组合发出单个项目
Observable.zip(
Observable.just(UpdatePicEvent(userId, file)).compose(updatePic())
Observable.just(UpdateProfileEvent(..params...)).compose(updateProfile())
mergePicAndProfile)
mergePicAndProfile
是BiFunction
接收两个结果并发出单个实体的地方。
答案 1 :(得分:0)
鉴于您对原始问题的评论,concat
可以为您提供帮助。文档的相关部分说:
Concat运算符连接多个Observable的输出,使它们像单个Observable一样,第一个Observable发出的所有项在第二个Observable发出的任何项之前发出(等等,如果有的话)超过两个。)
Concat等待订阅您传递给它的每个其他Observable,直到上一个Observable完成。
实现:
Observable.mergeDelayError(
Observable.just(UpdatePicEvent(userId, file)).compose(updatePic()),
Observable.just(UpdateProfileEvent(userId, params)).compose(updateProfile())
)
.concatWith(Observable.just(AllSuccessful())) // Or whatever
.onErrorReturn { when (it) {
is UpdatePicException -> UpdatePicError(it)
is UpdateProfileException -> UpdateProfileError(it)
}}
这有两个关键因素:
onErrorReturn
和updatePic
变换器中的updateProfile
,以便它们在失败时实际发出错误(可能是onErrorResumeNext { Observable.error(MyTypeOfException()) }
之类的内容。要做到这一点,流无法知道是否有错误(因为在项目中包装错误会使其与成功无法区分)mergeDelayError
让每个流独立于另一个流继续。如果您只使用merge
,则第一个失败将阻止另一个继续。(请注意,我稍微修改了原始代码,恕我直言,更具可读性)