结合两个 Observable<Void>s

Combining two Observable<Void>s

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

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 然后完成。

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

--

在我考虑的过程中,我可以接受按顺序进行的通话。那可能会更好...

即:

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

感谢您的帮助。

很抱歉我不知道 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() 运算符将 OnNextOnErrorOnCompleted 类型 T 可观察对象的通知转换为 OnNext Notification<T> 类型的可观察对象的通知。然后您可以 .Zip(...) 这些并检查您需要的条件。

我已经很好地学习了 RxSwift,现在可以回答这个问题了...

func doIt() -> Observable<Result> {
    Observable.zip(
        doA().map { Result.Success },
        doB().map { Result.Success }
            .catch { _ in Observable.just(Result.BFailed) }
    ) {  }
}

我相信 .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() 文档。

Projects each element of an observable sequence into a new sequence of observable sequences and then transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. It is a combination of map + switchLatest operator.