使用RxSwift在DispatchGroup之后返回对象

时间:2018-05-06 11:12:03

标签: iphone swift grand-central-dispatch rx-swift dispatch-queue

我正在使用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())
}

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

2 个答案:

答案 0 :(得分:0)

尝试添加

dispatchGroup.wait()

在你的行之后

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

而且,为什么不直接使用Rx运营商呢?

每一个都可以是observer.onNext,然后你试着观察这个可观察的三个事件,而不需要onCompleted

答案 1 :(得分:0)

我认为您可以使用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)