创建 observables 数组后在 RxSwift 中使用 zip 运算符

Posted

技术标签:

【中文标题】创建 observables 数组后在 RxSwift 中使用 zip 运算符【英文标题】:Using zip operator in RxSwift after creating an array of observables 【发布时间】:2018-08-16 05:17:32 【问题描述】:

我有一个newBid 对象,其中包含一些数据和图像数组。我想将所有图像和数据上传到服务器,zip 那些上传的 observables。如果我为dataimage1image2 创建单独的drivers,我会成功。

但我真正想做的是不对图像进行硬编码,因为数组可能包含 0 到 10 个图像。我想以编程方式创建 observables 数组并 zip 它们。

let dataSaved = saveTaps.withLatestFrom(newBid)
    .flatMapLatest  bid in
        return CustomerManager.shared.bidCreate(bid: bid)
            .trackActivity(activityIndicator)
            .asDriver(onErrorJustReturn: false)


let photoSaved0 = saveTaps.withLatestFrom(newBid)
    .flatMapLatest  bid in
        return CustomerManager.shared.bidUploadFile(image: bid.images[0])
            .trackActivity(activityIndicator)
            .asDriver(onErrorJustReturn: false)


let photoSaved1 = saveTaps.withLatestFrom(newBid)
    .flatMapLatest  bid in
        return CustomerManager.shared.bidUploadFile(image: bid.images[1])
            .trackActivity(activityIndicator)
            .asDriver(onErrorJustReturn: false)


saveCompleted = Driver.zip(dataSaved, photoSaved0, photoSaved1) return $0 && $1 && $2 

/*
// 0. Getting array of images from newBid
let images = newBid.map  bid in
    return bid.images


// 1. Creating array of upload drivers from array of images
let imageUploads = images.map  (images: [UIImage]) -> [Driver<Bool>] in
    var temp = [Driver<Bool>]()
    return temp


// 2. Zipping array of upload drivers to photoSaved driver
photoSaved = Driver
    .zip(imageUploads) // wait for all image requests to finish
    .subscribe(onNext:  results in
        // here you have every single image in the 'images' array
        results.forEach  print($0) 
    )
    .disposed(by: disposeBag)*/

如果我尝试zip imageUploads,在评论部分,我会收到错误:

Argument type 'SharedSequence<DriverSharingStrategy, [SharedSequence<DriverSharingStrategy, Bool>]>' does not conform to expected type 'Collection'

【问题讨论】:

【参考方案1】:

这样的事情怎么样?

let saves = saveTaps.withLatestFrom(newBid)
    .flatMapLatest  (bid: Bid) -> Observable<[Bool]> in
        let dataSaved = CustomerManager.shared.bidCreate(bid: bid)
            .catchErrorJustReturn(false)

        let photosSaved = bid.images.map 
            CustomerManager.shared.bidUploadFile(image: $0, bidID: bid.id)
                .catchErrorJustReturn(false)
        

        return Observable.zip([dataSaved] + photosSaved)
            .trackActivity(activityIndicator)
    
    .asDriver(onErrorJustReturn: []) // remove this line if you want an Observable<[Bool]>.

【讨论】:

谢谢,我会试试的。 仅供参考。 zip 操作员不会一次上传一张图片。它将同时开始所有上传,并在完成后报告。 我有一个错误:无法将类型 '(Bid) -> Observable' 的值转换为预期的参数类型 '() -> SharedSequence, _>' 您的 CustomerManager 函数返回什么?我假设他们返回 Observable. 是的。它返回 Observable【参考方案2】:

最终解决方案

let bidID: Driver<Int> = saveTaps.withLatestFrom(newBid)
    .flatMapLatest  bid in
        return CustomerManager.shared.bidCreate(bid: bid)
            .trackActivity(activityIndicator)
            .asDriver(onErrorJustReturn: 0)


saveCompleted = Driver.combineLatest(bidID, newBid)  bidID, newBid in
    newBid.uploadedImages.map 
        CustomerManager.shared.bidUploadFile(image: $0, bidID: bidID).asDriver(onErrorJustReturn: false)
    
    .flatMap  imageUploads in
        return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])
    .map (results:[Bool]) -> Bool in
        return !results.contains(false)

这是一个等价的组合版本:

let imageUploads: Driver<[Driver<Bool>]> = Driver.combineLatest(bidID, newBid)  bidID, newBid in
    newBid.uploadedImages.map 
        CustomerManager.shared.bidUploadFile(image: $0, bidID: bidID).asDriver(onErrorJustReturn: false)
    


let photosSaved: Driver<[Bool]> = imageUploads.flatMap  imageUploads in
    return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])


saveCompleted = photosSaved.map (results:[Bool]) -> Bool in
    return !results.contains(false)

【讨论】:

以上是关于创建 observables 数组后在 RxSwift 中使用 zip 运算符的主要内容,如果未能解决你的问题,请参考以下文章

Angular 7 - 对象的 Observables 数组的 Observable 数组

如何在模板 Angular 2 中呈现 observables 数组长度

我如何从可观察对象创建对象,该对象返回对象数组

RxJS 将 observable 附加到 typescript 中的 observable 数组列表

如何通过 Observable 属性对项目数组进行排序?

将 ko observables 组合成一个 ko observable 数组