如何在RxSwift中组合多个Observable

时间:2018-04-16 14:36:14

标签: swift rx-swift reactive

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

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

我怎么能:

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

谢谢!

1 个答案:

答案 0 :(得分:3)

  

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

查看方法imageObservable以了解可能的实现。

  

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

zipdocumentation)运算符可能就是您要查找的内容。

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也可能对您有用。