【问题标题】:RxSwift: chaining several actionsRxSwift:链接几个动作
【发布时间】:2016-02-11 16:16:34
【问题描述】:

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

  • 通过单独的调用将对象发送到后端
  • 第 1 步完成后将此数组批量存储到数据库中
  • 在第 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);
}

【问题讨论】:

    标签: swift chaining method-chaining rx-swift


    【解决方案1】:

    假设makeAPIRequestadditionalProcessing 都返回Observable&lt;SomeNotVoidType&gt;storeData 将数组作为参数并返回Observable&lt;Array&gt;。 这样,您可以执行以下操作:

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

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

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

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

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

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

    然后你又想为每个数组元素创建Observables,所以它们将代表额外的处理。请注意,您需要使用flatMapflatMapLates,否则您最终会得到像Observable&lt;Observable&lt;SomeType&gt;&gt; 这样的嵌套可观察对象。

    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);
    

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

    【讨论】:

    • 谢谢,Michał,这很有帮助!请问是否有任何资源/示例可以从中找到相关的 RxSwift 实践(文档除外)?
    • 我使用过 Reactive Cocoa 2.x,它具有非常相似的 API(但在 ObjC 中)和许多可用示例。不幸的是,RxSwift 还没有那么多,不妨看看 Eidolon 应用程序:github.com/artsy/eidolon。另外,我发现 RxSwift Playground 非常有用,您可以轻松地试验 Observables:github.com/ReactiveX/RxSwift#playgrounds
    猜你喜欢
    • 2015-01-18
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2016-05-20
    • 2015-12-21
    相关资源
    最近更新 更多