如何在 RxSwift 中组合多个 Observable

Posted

技术标签:

【中文标题】如何在 RxSwift 中组合多个 Observable【英文标题】:How to combine multi Observable in RxSwift 【发布时间】:2018-04-16 14:36:14 【问题描述】:

假设我为每个图像下载创建一个 Observable

for _ in 0...N 
    let s : Single<UIImage?> = fetchImage(from url)

我该怎么做:

创建一个新的 Observable 以在下载完成时发出事件 创建一个新的 Observable,以便在所有下载完成后仅发出完成事件

谢谢!

【问题讨论】:

【参考方案1】:

创建一个新的 Observable 以在下载完成时发出一个事件

查看方法imageObservable 以获得可能的实现。

创建一个新的 Observable 以在所有下载时仅发出完成的事件 完成了

zip (documentation) 运算符可能就是您要找的。​​p>

import RxSwift
import UIKit

enum CustomError: Error 
    case someError


class Executer 

    let disposeBag = DisposeBag()

    func execute() 
        let imageURLs = [
            URL(string: "http://via.placeholder.com/350x150")!, 
            URL(string: "http://via.placeholder.com/350x150")!
        ]
        let imageObservables = imageURLs.map  self.imageObservable(url: $0) 
        Observable
            .zip(imageObservables) // wait for all image requests to finish
            .subscribe(onNext:  images in
                // here you have every single image in the 'images' array
                images.forEach  print($0) 
            )
            .disposed(by: disposeBag)
     

     // wrap 'URLSession' datatask into an observable
     func imageObservable(url: URL) -> Observable<UIImage> 
        return Observable.create  observer in
            URLSession
                .shared
                .dataTask(with: url, completionHandler:  (data, response, error) -> Void in
                    if let error = error 
                        observer.onError(error)
                        return
                    
                    guard let data = data, let image = UIImage(data: data) else 
                        observer.onError(CustomError.someError)
                        return
                    
                    observer.onNext(image)
                    observer.onCompleted()
                )
                .resume()
            return Disposables.create()
        
    

此answer 也可能与您相关。

【讨论】:

这正是我想要的。非常感谢。 或者使用 combineLatest reactivex.io/documentation/operators/combinelatest.html 当你所有的 observables 都具有相同类型的元素时,合并最新是很棒的。如果您需要按顺序执行,事情就会变得复杂。

以上是关于如何在 RxSwift 中组合多个 Observable的主要内容,如果未能解决你的问题,请参考以下文章

如何将 RxSwift 转换为组合框架

RxSwift 对 Observable 的扩展,其中 Element 是 Result<>

如何在 RxSwift 中将多个数据模型绑定到 TableView

rxswift:如何获取 Observable<Any> 导致 Observable<[Category]> 的组合?

RxSwift:如何通过多个视图模型传递控制事件

RxSwift:使用运算符组合下载照片并保存在本地