RxSwift:链接几个动作

时间:2016-02-11 16:16:34

标签: swift chaining method-chaining rx-swift

假设我们有一个AnObject实例数组,需要执行以下操作序列:

  • 通过单独的呼叫将对象发送到后端
  • 步骤1完成后
  • 将此数组批量存储到DB
  • 在第2步完成后为每个项目执行额外处理

我们只想在所有这些步骤执行后(或出现错误)接收信号。通过 RxSwift 实现此目的的正确方法是什么?它实际上可行吗?

请在下面找到我的原型功能。不幸的是,我没有提供有效的链接代码示例,所以没有什么可以演示的。

func makeAPIRequest(object: AnObject) -> Observable<Void> {
    ...
}

func storeData(data: [AnObject]) -> Observable<Void> {
    ...
}

func additionalProcessing(object: AnObject) -> Observable<Void> { 
    ...
} 

func submitData()
{
   let data: [AnObject] = ...;

   let apiOperations = data.map{ makeAPIRequest($0) };
   let storageOperation = storeData(data);
   let processingOperations = data.map{ additionalProcessing($0) };

   ... // some code to chain steps 1-3
   .subscribe { (event) -> Void in
       // should be called when operations from step 3 finished  
   }.addDisposableTo(disposeBag);
}

1 个答案:

答案 0 :(得分:9)

我们假设makeAPIRequestadditionalProcessing都返回Observable<SomeNotVoidType>storeData将数组作为参数并返回Observable<Array>。 这样,您可以执行以下操作:

首先,创建一个Observables数组,表示将单个对象发送到后端。然后使用toObservable方法,以便稍后可以转换结果信号:

let apiOperations = data.map{ makeAPIRequest($0) }.toObservable()

然后使用merge运算符生成Observable,仅在所有API调用完成时才会完成。您还可以使用toArray运算符,它将API调用结果放入一个数组中:

let resultsArray = apiOperations.merge().toArray()

这将为您提供Observable<Array<ApiResult>>,当所有API操作成功完成时,它会发送一个Next事件。现在您可以将结果存储在数据库中:

let storedResults = resultsArray.flatMap { storeDatabase($0) }

然后你想再为每个数组元素设置Observables,这样它们就代表了额外的处理。请注意,您需要使用flatMapflatMapLates,否则最终会使用Observable<Observable<SomeType>>等嵌套的观察对象。

let additionalProcessingResults = storedResults.flatMap {
      return $0.map(additionalProcessing).toObservable()
    }.flatMapLatest { return $0 }

然后,您可以订阅成功完成额外处理(或者您可以对其单独结果执行某些操作):

additionalProcessingResults.subscribe { (event) -> Void in
       // should be called when operations from step 3 finished  
   }.addDisposableTo(disposeBag);

请注意,您不需要所有中间变量,我只是让它们描述所有步骤。