【问题标题】:How to user ReactiveX to execute async's in sequence如何使用 ReactiveX 按顺序执行异步
【发布时间】:2016-08-09 23:31:32
【问题描述】:

如何利用ReactiveX 依次执行异步调用? 即,在第一个调用完成后执行第二个调用。

更具体地说,我在 iOS 中使用 RxSwift,我想要链接在一起的异步是 UIView 动画(而不是在第一个动画的 completion 块内调用第二个动画)。

我知道我还有其他选择,例如 Easy Animation,但我想利用 Rx,因为我已经将它用于流。

另外,一种解决方案是(对于 3 个链式动画):

_ = UIView.animate(duration: 0.2, animations: {
        sender.transform = CGAffineTransformMakeScale(1.8, 1.8)
    })
    .flatMap({ _ in
        return UIView.animate(duration: 0.2, animations: {
            sender.transform = CGAffineTransformMakeScale(0.8, 0.8)
        })
    })
    .flatMap({ _ in
        return UIView.animate(duration: 0.2, animations: {
            sender.transform = CGAffineTransformIdentity
        })
    })
    .subscribeNext({ _ in })

但我正在寻找更优雅的东西,使用 Rx 的正确方法。

【问题讨论】:

  • 你的代码示例怎么了?你的意思是它是伪代码吗?您在Void 上调用flatMap,而不是SequenceTypeObservable。另外,它是animateWithDuration:animations:,而不是animate:animations:。我不确定您包含该代码的意图。
  • 我创建了 animate:... 方法来返回一个可观察的,所以不,不是伪代码

标签: ios swift asynchronous rx-swift reactivex


【解决方案1】:

我不认为使用 Rx 会更干净,但您可以这样做:

let animation1 = Observable<Void>.create { observer in
    UIView.animateWithDuration(0.2,
        animations: {
            // do your animations
        }, completion: { _ in
            observer.onCompleted()
        })
    return NopDisposable.instance
}

let animation2 = Observable<Void>.create { observer in
    UIView.animateWithDuration(0.2,
        animations: {
            // do your animations
        }, completion: { _ in
            observer.onCompleted()
        })
    return NopDisposable.instance
}

Observable.of(animation1, animation2)
    .concat()
    .subscribe()
    .addDisposableTo(disposeBag)

如果你创建一个函数来为你构造Observable&lt;Void&gt;s 也会更简洁。

func animation(duration: NSTimeInterval, animations: () -> Void) -> Observable<Void> {
    return Observable<Void>.create { observer in
        UIView.animateWithDuration(duration,
            animations: animations,
            completion: { _ in
                observer.onCompleted()
            })
        return NopDisposable.instance
    }

我猜想使用Rx 而不仅仅是animateWithDuration:animations: 链接的好处是您不必将动画嵌套在完成块中。这样,您可以自行定义它们,然后根据需要进行组合。

作为RxSwift 的替代品,请查看PromiseKit。 RxSwift 对于您的动画回调需求来说有点过分了。 This blog post 尤其重要。

【讨论】:

  • 不会Observable.of(animation1, animation2).concat() 并行运行它们?
  • 除了Rx 之外,您还会使用其他东西吗?这正是我的问题,我不想嵌套回调。
  • 另外,为什么我需要.addDisposableTo(disposeBag)?观察者完成后不应该自己走吗?
  • concat 将连续运行 Observable,只有在当前一个已发送 Completed 事件后才会继续运行下一个。我确定有一个更适合动画控制的库,但是我没有搜索过。这确实避免了(耦合的)嵌套回调,所以如果这就是你所关心的,那很好。您仍然需要 addDisposableTo 调用,以便在释放 disposeBag 时正确处理 Observable(因此,大概是视图控制器或拥有它的人)。
  • 但是订阅完成后不会自己处理掉吗?
【解决方案2】:

对于@Rodrigo Ruiz 来说可能为时已晚,但我相信它可能会帮助其他碰巧看到这篇文章的开发人员(就像我一样)。

RxAnimated 在 GitHub 上免费提供:https://github.com/RxSwiftCommunity/RxAnimated

你可以开始使用这个blog post

一个小的披露者 - 我没有连接到这个项目或以任何方式发布 - 我只是在为我的动画搜索反应式解决方案时发现它:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2019-12-07
    • 2012-04-01
    • 1970-01-01
    相关资源
    最近更新 更多