RxSwift:链可完成到可观察

jul*_*adi 4 observable ios swift rx-swift

我想将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)
Run Code Online (Sandbox Code Playgroud)

尽管正在调用fetchUserInformationobserver(.completed),并且成功获取了用户信息,但我无法在订阅时捕获onCompleted(仅在flatMap之前))。

有没有一种干净的方法来实现这一目标?

flatMap调用之后已经尝试了.materialized(),以获取

    Observable<Event<Never>>
Run Code Online (Sandbox Code Playgroud)

而不是

    Observable<Never>
Run Code Online (Sandbox Code Playgroud)

它也不起作用。

Sha*_*ali 7

正确的解决方案是使用“ andThen”运算符。

someCompletable
   .andThen(someObservable) 
Run Code Online (Sandbox Code Playgroud)

编辑:只需阅读其余的代码-我不确定您为什么要使用a Completable,因为似乎您实际上是从该流中返回了一些元素。

您可能需要使用a Single或Plain-ol'observable来中继该值,而无需使用外部中继。


小智 5

我认为您可以执行以下操作:

login()
    .flatMap{ userId -> Observable<Void> in
        return fetchUserInformation(userId).andThen(.just(Void()))
    }.subscribe(onNext: { _ in
        ...
    }).disposed(by: disposeBag)
Run Code Online (Sandbox Code Playgroud)