【问题标题】:Get values from two apis into two different Observable and perform some operation从两个api中获取值到两个不同的Observable中并执行一些操作
【发布时间】:2021-05-08 01:44:42
【问题描述】:

我有两个独立的 observables。当它们都完成并且它们每个都提供了一个数组时,我需要执行一些操作。

let myObj1Array = myObj1Manager.getMyObj1List()//returns Observable<[MyObj1]>
let myObj2Array = myObj2Manager.getMyObj2List()//returns Observable<[MyObj2]>

现在我需要比较 myObj1Array 和 myObj2Array 的值,并在此基础上使用两个数组中的值创建另一个数组。我知道如何订阅 1 个变量,但不确定如何观察两个不同数组的完成情况。

编辑: 我也尝试过以下操作,但我只从第一个数组中获取值:

let myObj1Array = myObj1Manager.getMyObj1List()
        let myObj2Array = myObj1Array.flatMap { _ in myObj2Manager.getMyObj2List() }
        Observable.combineLatest(myObj1Array, myObj2Array)
        .subscribe(onNext: { (sss, sds) in
            print(sss)
        })
        .addDisposableTo(disposeBag)

我实际上对如何处理这种情况一无所知。

编辑2: 获取第一个数组中的 observables 的函数:

func getMyObj1List() -> Observable<[MyObj1]> {
        return Observable.create { observer -> Disposable in
            self.specialsRest.getMyObj1List { response, error in
                if let error = error {
                    observer.onError(Exception(error))
                    return
                }
                guard let saleItems = MyObj1.decode(data: response?.data) else {
                    observer.onError(Exception("Could not decode specials!"))
                    return
                }
                queueBackground.async {
                   
                    observer.onNext(saleItems)
                    observer.onCompleted()
                }

            }
            return Disposables.create { self.specialsRest.cancel() }
        }
    }

【问题讨论】:

  • 你能说明一下代码,你 1) 设置你的 observables(它看起来像你的第一个块,但看起来它正在返回一些东西)和 2) 你从观察中获取数据的位置? let myObj1Array = myObj1Manager.getMyObj1List() 这是设置观察还是取回数据?我想我看不到您在哪里异步获取数据,即当使用数据调用观察者时。

标签: ios swift rx-swift


【解决方案1】:

DispatchGroup 可能是这里的路。

https://developer.apple.com/documentation/dispatch/dispatchgroup

当所有工作项完成执行时,组执行其完成处理程序。您也可以同步等待组中的所有任务完成执行。

var dg:DispatchGroup = DispatchGroup()

//Wherever you start your observables.
//Start Observer1
dg.enter()

//Start Observer2
dg.enter()

...
...
...

//Wherever you retrieve data
SomeAsyncFuncForObserver1 {
    //Get Data
    dg.leave()
}

SomeAsyncFuncForObserver2 {
    //Get Data
    dg.leave()
}

dg.notify(queue: .main) {
    print("all finished.")
}

【讨论】:

    【解决方案2】:

    我相信您需要使用zip 而不是combineLatest。来自docs

    CombineLatest 运算符的行为方式与 Zip 类似,但同时 Zip 仅在每个已压缩的源 Observable 具有 发出一个先前解压缩的项目,CombineLatest 发出一个项目 每当任何源 Observable 发出一个项目时(只要每个 的源 Observables 已发出至少一项)。

    Observable
        .zip(myObj1Array, myObj2Array)
        .subscribe(onNext: { (sss, sds) in
            print(sss)
        })
        .addDisposableTo(disposeBag)
    

    【讨论】:

    • 假设myObj1ArraymyObj2Array 都只发出一个值然后完成,zipcombineLatest 的行为相同。仅当至少一个输入发出多个 next 事件时,它们的行为才会有所不同。
    猜你喜欢
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多