首页 > 解决方案 > 使用 RxSwift 在 DispatchGroup 之后返回对象

问题描述

我正在使用 DispatchGroup 从 3 个不同的 API 下载数据,一旦完成,我想从我的函数中返回新创建的合并对象。现在虽然 DispatchGroup 工作正常并且我正在获取数据,但我无法将其返回给调用函数。以下是我的功能:

func getHowToInfo(materialNo: String) -> Observable<HowToInfo> {
    return Observable.create{ observer in
        let dispatchGroup = DispatchGroup()

        _ = self.getMaterialInfo(materialNo: materialNo).subscribe(onNext:{ material in

            let howto = HowToInfo(videos: [], documents: [], applications: [])

            if (material.documentTargetId?.count)! > 0 {
                dispatchGroup.enter()
                _ = self.materialRepo?.API1(targetIDs: material.documentTargetId!).subscribe(onNext:{documents in
                    howto.documents = documents
                    dispatchGroup.leave()
                }, onError: { (error) in
                    dispatchGroup.leave()
                })
            }
            if (material.applicationDescription?.count)! > 0 {
                dispatchGroup.enter()
                _ = self.materialRepo?.API2(materialNo: materialNo).subscribe(onNext:{applications in
                    howto.applications = applications
                    dispatchGroup.leave()
                }, onError: { (error) in
                    dispatchGroup.leave()
                })
            }
            if ((material.videoApplicationTargetId?.count) != nil && (material.videoApplicationTargetId?.count)! > 0) {
                dispatchGroup.enter()
                _ = self.materialRepo?.API3(targetIDs: material.videoApplicationTargetId!).subscribe(onNext:{videos in
                    howto.videos = videos
                    dispatchGroup.leave()
                }, onError: { (error) in
                    dispatchGroup.leave()
                })
            }else if ((material.videoSupportTargetId?.count) != nil && (material.videoSupportTargetId?.count)! > 0) {
                dispatchGroup.enter()
                _ = self.materialRepo?.API4(targetIDs: material.videoSupportTargetId!).subscribe(onNext:{videos in
                    howto.videos = videos
                    dispatchGroup.leave()
                }, onError: { (error) in
                    dispatchGroup.leave()
                })
            }

            dispatchGroup.notify(queue: .main, execute: {
                print("All functions complete ")
                observer.onNext(howto)
                observer.onCompleted()
            })
        })
        return Disposables.create()
    }
}

调用函数:

func loadHowToUseList(materialNo: String){
    self.serviceMaterial.getHowToInfo(materialNo: materialNo).subscribe({
        howToUse in
        print(howToUse)
    }).disposed(by: DisposeBag())
}

我无法在上面的订阅方法中获取我的对象,它永远不会运行。

标签: iphoneswiftgrand-central-dispatchrx-swiftdispatch-queue

解决方案


我认为您可以使用 combineLatest 和 skipWhile 运算符实现所需的行为。大致实现是这样的:

    let api1 = Observable.of(["documents"])    //Replace with observable to download docs
    let api2 = Observable.of(["applications"]) //Replace with observable to download apps
    let api3 = Observable.of(["videos"])       //Replace with observable to download videos

    Observable.combineLatest(api1, api2, api3){(docs, apps, videos) in
        return (docs, apps, videos)
    }.skipWhile{ (docs, apps, videos) in
        return docs.count == 0 && apps.count == 0 && videos.count == 0
    }.subscribe(onNext:{(docs, apps, videos) in

    })
    .disposed(by:disposeBag)

推荐阅读