【问题标题】:Return object after DispatchGroup with RxSwift使用 RxSwift 在 DispatchGroup 之后返回对象
【发布时间】:2018-10-16 08:43:30
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      尝试添加

      dispatchGroup.wait()
      

      在你的台词之后

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

      还有,为什么不直接使用 Rx 运算符呢?

      其中每一个都可以是observer.onNext,那么你尝试观察这个observable的三个事件,就不需要onCompleted

      【讨论】:

      • 其实这些调用都是随机的,不知道哪个会先完成,想等3个调用都完成后返回对象
      • 我还添加了 dispatchGroup.wait() 但现在没有调用通知块。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多