2015-10-31 20 views
6

Tôi vẫn là người mới hoạt động và tôi đang tìm kiếm trợ giúp.Kết hợp hai Quan sát <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 

} 

Trên đây là những gì tôi nghĩ là tôi muốn ... Các chức năng ban đầu doA()doB() mạng bọc gọi để họ cả hai sẽ phát ra một tín hiệu và sau đó Complete (hoặc Error mà không phát ra bất kỳ Next sự kiện.) Nếu doA() Hoàn thành nhưng doB() lỗi, tôi muốn doIt() phát ra .BFailed và sau đó hoàn tất.

Có vẻ như tôi nên sử dụng zip hoặc combineLatest nhưng tôi không biết làm cách nào để biết chuỗi nào bị lỗi nếu tôi làm điều đó. Tôi cũng khá chắc chắn rằng catchError là một phần của giải pháp, nhưng tôi không chắc chắn chính xác vị trí đặt nó.

-

Khi tôi đang nghĩ về điều đó, tôi đồng ý với các cuộc gọi diễn ra tuần tự. Đó thậm chí có thể tốt hơn ...

IE:

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

Cảm ơn sự giúp đỡ nào.

Trả lời

0

Tôi xin lỗi vì tôi không biết cú pháp cho nhanh, vì vậy tôi viết câu trả lời bằng C#. Mã phải được dịch trực tiếp.

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); 

Về cơ bản các nhà điều hành .Materialize() biến OnNext, OnError, và OnCompleted thông báo cho một quan sát của loại T vào OnNext thông báo cho một quan sát của loại Notification<T>. Sau đó, bạn có thể .Zip(...) những điều này và kiểm tra các điều kiện bắt buộc của mình.

+0

Hmm ... Cảm ơn câu trả lời, nhưng RxSwift không có phương pháp vật chất hóa. Ít nhất là chưa. –

0

Tôi dường như đã tự tìm thấy câu trả lời ... Phải thừa nhận rằng giải pháp này không chờ tin nhắn đầy đủ từ số doA() hoặc doB(). Thay vào đó nó phát ra đối tượng Result trên tín hiệu onNext, nhưng vì đây là các cuộc gọi mạng, sẽ chỉ có một onNext trước khi hoàn thành. Có lẽ nghĩ rằng tôi phải đợi cho đến khi hoàn thành là điều khiến tôi khó hiểu.

func doIt() -> Observable<Result> { 
    return doA().flatMap { 
     return doB().map { 
      .Success 
     } 
     .catchError { 
      just(.BFailed) 
     } 
    } 
} 
1

Tôi tin rằng .flatMapLatest() là những gì bạn đang tìm kiếm, chuỗi các yêu cầu quan sát được của bạn.

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) 

Và đây là .flatMapLatest() doc trong RxSwift.

dự án mỗi phần tử của một chuỗi quan sát được vào một chuỗi mới của trình tự quan sát và sau đó biến đổi một chuỗi quan sát của chuỗi quan sát được vào một giá trị chuỗi sản xuất quan sát chỉ từ chuỗi quan sát gần đây nhất. Đó là sự kết hợp của nhà điều hành map + switchLatest.

Các vấn đề liên quan