Возврат объекта после DispatchGroup с помощью RxSwift - PullRequest
0 голосов
/ 06 мая 2018

Я использую 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 голосов
/ 10 мая 2018

Я думаю, что вы можете достичь желаемого поведения, используя операторы 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)
0 голосов
/ 06 мая 2018

Попробуйте добавить

dispatchGroup.wait()

После ваших строк

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

А также, почему бы просто не использовать сами операторы Rx?

Каждое из этих значений может быть observer.onNext, затем вы пытаетесь наблюдать три события этой наблюдаемой, и нет необходимости в onCompleted

...