RxSwift链接彼此依赖的请求

时间:2018-04-13 05:55:40

标签: swift reactive-programming rx-swift

我还在学习Rx,我正在尝试使用RxSwift来发出3个相互依赖的请求。

* DocumentsA
 - CollectionA
   * DocumentsB
    - CollectionB
     * DocumentsC
      - CollectionC

模型是这样的:

struct DocumentA {
  let documentsB: [DocumentB] 
}

struct DocumentB {
  let documentsC: [DocumentC] 
}

struct DocumentsC {
  let name: String 
}

所以使用RxSwift,我试图为每个文档使用不同的方法请求文档的每个级别:

func fetchDocumentsA() -> Observable<DocumentA> {
  return Observable.create { observer in
    fetchDocumentsB().subscribe(onNext: { documentB in
      if let documentA = DocumentA(documentB: documentB) {
        observer.onNext(documentA)
      }
    }, onError: nil, onCompleted: {
      observer.onCompleted()
    }, onDisposed: nil).disposed(by: self.disposeBag)
    return Disposables.create()
  }
}

func fetchDocumentsB() -> Observable<DocumentB> {
  return Observable.create { observer in
    fetchDocumentsC().subscribe(onNext: { documentC in
      if let documentB = DocumentB(documentC: documentC) {
        observer.onNext(documentB)
      }
    }, onError: nil, onCompleted: {
      observer.onCompleted()
    }, onDisposed: nil).disposed(by: self.disposeBag)
    return Disposables.create()
  }
}

func fetchDocumentsC() -> Observable<DocumentC> {
  return Observable.create { observer in
    fetchName().subscribe(onNext: { name in
      observer.onNext(DocumentC(name: name))
    }, onError: nil, onCompleted: {
      observer.onCompleted()
    }, onDisposed: nil).disposed(by: self.disposeBag)
    return Disposables.create()
  }
}

有更好的方法吗?这看起来很复杂。

1 个答案:

答案 0 :(得分:3)

在这种情况下,您可以使用map函数更好地使用此功能,例如下面的示例。

  

Map运算符将您选择的函数应用于源Observable发出的每个项目,   并返回一个Observable,它发出这些函数的结果   应用。   ReactiveX

func fetchDocumentsA() -> Observable<DocumentA> {
    return fetchDocumentsB().map { (documentB) -> DocumentA in
        DocumentA(documentB: documentB)
    }
}

func fetchDocumentsB() -> Observable<DocumentB> {
    return fetchDocumentsC().map { (documentC) -> DocumentB in
        DocumentB(documentC: documentC)
    }
}

func fetchDocumentsC() -> Observable<DocumentC> {
    return fetchName().map { (name) -> DocumentC in
        return DocumentC(name: name)
    }
}