我仍然是一个反应新手,我正在寻求帮助。
func doA() -> Observable<Void>
func doB() -> Observable<Void>
enum Result {
case Success
case BFailed
}
func doIt() -> Observable<Result> {
// start both doA and doB.
// If both complete then emit .Success and complete
// If doA completes, but doB errors emit .BFailed and complete
// If both error then error
}
以上是我认为我想要的...初始函数doA()
和doB()
包装网络调用,因此它们将发出一个信号然后Complete
(或{{1没有发出任何Error
事件。)如果Next
完成但doA()
错误,我希望doB()
发出doIt()
然后完成。
感觉我应该使用.BFailed
或zip
,但我不知道如果我这样做,如何知道哪个序列失败了。我也非常确定combineLatest
是解决方案的一部分,但我不确定将其放在何处。
-
正如我想的那样,我可以按顺序发出呼叫。那甚至可能更好......
IE:
catchError
感谢您的帮助。
答案 0 :(得分:1)
我相信.flatMapLatest()
正是您所寻找的,链接您的可观察请求。
doFirst()
.flatMapLatest({ [weak self] (firstResult) -> Observable<Result> in
// Assuming this doesn't fail and returns result on main scheduler,
// otherwise `catchError` and `observeOn(MainScheduler.instance)` can be used to correct this
// ...
// do something with result #1
// ...
return self?.doSecond()
}).subscribeNext { [weak self] (secondResult) -> Void in
// ...
// do something with result #2
// ...
}.addDisposableTo(disposeBag)
这里是RxSwift中的.flatMapLatest()
doc。
将可观察序列的每个元素投射到新的可观察序列序列中 将可观察的可观察序列序列转换为可观察序列,仅从最近的可观察序列产生值。它是
map
+switchLatest
运算符的组合。
答案 1 :(得分:0)
我很抱歉我不知道swift的语法,所以我在c#中写了答案。代码应该可以直接翻译。
var query =
doA
.Materialize()
.Zip(doB.Materialize(), (ma, mb) => new { ma, mb })
.Select(x =>
x.ma.Kind == NotificationKind.OnError
|| x.mb.Kind == NotificationKind.OnError
? Result.BFailed
: Result.Success);
.Materialize()
运算符基本上将OnNext
,OnError
和OnCompleted
通知的T
类型OnNext
通知变为Notification<T>
通知类型.Zip(...)
的可观察量。然后,您可以p.shutdown()
这些并检查您所需的条件。
答案 2 :(得分:0)
I seem to have found an answer myself... Admittedly this solution doesn't wait for the complete message from either doA()
or doB()
. Instead it emits the Result object on the onNext signal, but since these are network calls, there will only be one onNext before the completion anyway. Maybe thinking I had to wait for the complete was the thing that was making it hard for me to understand.
func doIt() -> Observable<Result> {
return doA().flatMap {
return doB().map {
.Success
}
.catchError {
just(.BFailed)
}
}
}