6

我仍然是一个被动的新手,我正在寻求帮助。

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(或Error不发出任何Next事件)。如果doA()完成但doB()出错,我想doIt()发出.BFailed然后完成。

感觉就像我应该使用zip或者combineLatest但我不确定如果我这样做了如何知道哪个序列失败了。我也很确定这catchError是解决方案的一部分,但我不确定该放在哪里。

--

正如我正在考虑的那样,我可以接受依次发生的呼叫。那可能会更好...

IE:

Start doA() 
    if it completes start doB() 
        if it completes emit .Success 
        else emit .BFailed.
    else forward the error.

谢谢你的帮助。

4

3 回答 3

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)

这是.flatMapLatest()RxSwift 中的文档。

将可观察序列的每个元素投影到可观察序列的新序列中,然后将可观察序列的可观察序列转换为仅从最近的可观察序列产生值的可观察序列。它是map+switchLatest运算符的组合。

于 2016-03-19T23:32:19.093 回答
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()操作符将 observable 类型的OnNextOnErrorOnCompleted通知转换为 observable 类型TOnNext通知Notification<T>。然后,您可以.Zip(...)检查这些并检查您需要的条件。

于 2015-10-31T23:09:26.043 回答
0

我自己似乎找到了答案......诚然,这个解决方案不会等待来自doA()or的完整消息doB()。相反,它在 onNext 信号上发出 Result 对象,但由于这些是网络调用,所以在完成之前只会有一个 onNext 。也许认为我必须等待完成是让我难以理解的事情。

func doIt() -> Observable<Result> {
    return doA().flatMap {
        return doB().map { 
            .Success 
        }
        .catchError {
            just(.BFailed)
        }
    }
}
于 2015-11-01T01:40:24.090 回答