RxSwift: 链 Completable 到 Observable
Posted
技术标签:
【中文标题】RxSwift: 链 Completable 到 Observable【英文标题】:RxSwift: Chain Completable to Observable 【发布时间】:2018-06-08 05:25:24 【问题描述】:我想将 Completable 链接到可观察元素。调用 flatMap 后,onCompleted 和 onError 回调似乎不会在订阅时调用。
var user = PublishRelay<User>()
func fetchUserInformation(_ userId: String) -> Completable
return Completable.create observer in
apiService.fetchInformation(for: userId, completion: response in
if let name = response?.name
user.accept(User(name: name))
observer(.completed)
else
observer(.error(ServiceError.userInformation))
)
return Disposables.create()
login()
.flatMap userId in fetchUserInformation(userId)
.subscribe(
onCompleted:
print("Success!") // Not being called at all
,
onError: error in
print(error) // Not being called at all
).disposed(by: disposeBag)
虽然 fetchUserInformation 和 observer(.completed) 被调用并且用户信息被成功获取,但我无法捕捉到 onCompleted em> 订阅时(仅当前面有 flatMap 时)。
有没有一种干净的方法来实现这一点?
已经在 flatMap 调用之后尝试了 .materialized() 以获得
Observable<Event<Never>>
而不是一个
Observable<Never>
它也不起作用。
【问题讨论】:
如果Completable
不符合您的需求,请不要使用...此外,不会调用 onCompleted
,因为当您的内部可观察 (fetchUserInformation
) 完成时,这并没有完成您的外部可观察对象:在下一次登录值时,它将再次触发fetchUserInformation
。
【参考方案1】:
正确的解决方案是使用“andThen”运算符。
someCompletable
.andThen(someObservable)
编辑:
只需阅读您的其余代码 - 我不确定您为什么要使用 Completable
,因为您似乎实际上是从该流中返回了一些元素。
您可能希望使用Single
或Plain-ol' observable 来中继该值,而无需使用外部中继。
【讨论】:
很高兴知道 -1 的用途 :)【参考方案2】:我认为你可以这样做:
login()
.flatMap userId -> Observable<Void> in
return fetchUserInformation(userId).andThen(.just(Void()))
.subscribe(onNext: _ in
...
).disposed(by: disposeBag)
【讨论】:
【参考方案3】:据我所知,您无法将 Completable 转换为 Observable,因为后者会省略值,而 Completable 不会。
我猜 flatMap 正在从 Login 返回 Observables,然后您将其转换为 Completables,这就是它失败的原因
【讨论】:
以上是关于RxSwift: 链 Completable 到 Observable的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift 可观察到的错误停止链 - 带有 Rx 的 Web 服务,如何恢复?
java 列表输入到Completable future join结果
RxSwift,依赖链的下载返回相同的 Observable 类型