RxSwift - 可以从自己的订阅中处理序列吗?
RxSwift - Is it ok to dispose sequence from its own subscribe?
假设我们有一个以回调结束的函数,如果回调被调用,我们想做一些事情。
可以是任何函数,我在这个例子中使用请求用户确认的函数。
func userConfirmed(callback: () -> Void) {
// Here we would show confirmation dialog and if user clicks "Confirm", the callback is called, otherwise function does nothing
}
现在我们有了一个 Rx 序列,我们想为序列的每个元素调用我们的函数。如果用户确认操作(调用回调),则应处理序列,以便不能多次执行已确认的操作,否则序列应继续。
我会像这样使用 DisposeBag,这似乎是错误的:
var db = DisposeBag()
button.rx.tap.subscribe(onNext: {
userConfirmed {
db = DisposeBag()
// Do stuff
}
}).disposed(by: db)
我能想到的替代解决方案是使用 flatMap
、Observable.create
和 take
,这应该不会引起任何问题,但对于这样一个简单的任务来说似乎真的很复杂。
button.tap
.flatMap {
return Observable<Void>.create { event in
userConfirmed {
event.onNext(())
event.onCompleted()
}
return Disposables.create()
}
}
.take(1)
.subscribe(onNext: {
// Do stuff
}
.disposed(by: db)
问题
- 像这样直接在订阅中使用 DisposeBag 处理序列是否可以,还是我必须使用替代解决方案? (为什么?)
- 有没有比所提供的两个更好的解决方案?
我知道这个例子可以通过disabling/hiding用户确认后的按钮来解决,但这不是问题的重点
让乐高积木在许多情况下如此容易重新配置和重用的原因是它们都符合相同的界面(它们的顶部都有相同配置的双头螺栓)。想象一下有多痛苦如果只有一些块具有方钉图案,而其他块具有六角形图案,还有一些使用其他图案,那将是构建一些东西...
iOS 生态系统有大约 9 种不同的数据推送模式(如下所列)。编写应用程序所固有的复杂性很大程度上来自于必须将所有这些不同的模式集成到一个连贯的整体中。让 Rx 工作起来如此愉快的一件事是它提供了一种使所有这些都符合单一、简单和一致的模式的方法。就像乐高积木一样,让所有的子系统都遵循一个模式可以让你的代码不那么痛苦。根据需要更容易构建和重新配置。
为此,将回调函数转换为 returns Observable 的函数似乎很痛苦,但通过这样做,您的函数将成为整个生态系统的一部分,因此它效用得到改善。
所有这些都是说 Observable.create
路线至少在我看来是解决这个问题的最佳方法。我会把它移到它自己的函数中,而不是在 flatMap 中执行 Observable.create
。这样做会使调用站点更干净:
func userConfirmed() -> Observable<Void> {
Observable.create { observer in
userConfirmed {
observer.onNext(())
observer.onCompleted()
}
return Disposables.create()
}
}
更好的方法是使用一个已经将您需要的功能包装到 Observable 中的库。我的 CLE library as well as RxModal 两者都有用于呈现(警报)视图控制器并根据用户选择从中发出值的工具。
好吧...以上是我在论证为什么你应该使用“对于这样一个简单的任务来说似乎真的很复杂”的方法,但如果这不是你的事并且你想混合和匹配系统(哪个使您的代码更复杂)那么您的 disposeBag 想法就可以了。不过用一个袋子装一个一次性的感觉有点奇怪...
正如所承诺的,这里列出了 Apple 让我们推送数据的所有方式:
- 关闭
- target/action(UIControl 又名 IBAction)
- 代表
- 通知(通知中心)
- KVO
- 设置变量(是否 set/will 设置)
- 子分类抽象基础类
- async/await
- 出版商
假设我们有一个以回调结束的函数,如果回调被调用,我们想做一些事情。
可以是任何函数,我在这个例子中使用请求用户确认的函数。
func userConfirmed(callback: () -> Void) {
// Here we would show confirmation dialog and if user clicks "Confirm", the callback is called, otherwise function does nothing
}
现在我们有了一个 Rx 序列,我们想为序列的每个元素调用我们的函数。如果用户确认操作(调用回调),则应处理序列,以便不能多次执行已确认的操作,否则序列应继续。
我会像这样使用 DisposeBag,这似乎是错误的:
var db = DisposeBag()
button.rx.tap.subscribe(onNext: {
userConfirmed {
db = DisposeBag()
// Do stuff
}
}).disposed(by: db)
我能想到的替代解决方案是使用 flatMap
、Observable.create
和 take
,这应该不会引起任何问题,但对于这样一个简单的任务来说似乎真的很复杂。
button.tap
.flatMap {
return Observable<Void>.create { event in
userConfirmed {
event.onNext(())
event.onCompleted()
}
return Disposables.create()
}
}
.take(1)
.subscribe(onNext: {
// Do stuff
}
.disposed(by: db)
问题
- 像这样直接在订阅中使用 DisposeBag 处理序列是否可以,还是我必须使用替代解决方案? (为什么?)
- 有没有比所提供的两个更好的解决方案?
我知道这个例子可以通过disabling/hiding用户确认后的按钮来解决,但这不是问题的重点
让乐高积木在许多情况下如此容易重新配置和重用的原因是它们都符合相同的界面(它们的顶部都有相同配置的双头螺栓)。想象一下有多痛苦如果只有一些块具有方钉图案,而其他块具有六角形图案,还有一些使用其他图案,那将是构建一些东西...
iOS 生态系统有大约 9 种不同的数据推送模式(如下所列)。编写应用程序所固有的复杂性很大程度上来自于必须将所有这些不同的模式集成到一个连贯的整体中。让 Rx 工作起来如此愉快的一件事是它提供了一种使所有这些都符合单一、简单和一致的模式的方法。就像乐高积木一样,让所有的子系统都遵循一个模式可以让你的代码不那么痛苦。根据需要更容易构建和重新配置。
为此,将回调函数转换为 returns Observable 的函数似乎很痛苦,但通过这样做,您的函数将成为整个生态系统的一部分,因此它效用得到改善。
所有这些都是说 Observable.create
路线至少在我看来是解决这个问题的最佳方法。我会把它移到它自己的函数中,而不是在 flatMap 中执行 Observable.create
。这样做会使调用站点更干净:
func userConfirmed() -> Observable<Void> {
Observable.create { observer in
userConfirmed {
observer.onNext(())
observer.onCompleted()
}
return Disposables.create()
}
}
更好的方法是使用一个已经将您需要的功能包装到 Observable 中的库。我的 CLE library as well as RxModal 两者都有用于呈现(警报)视图控制器并根据用户选择从中发出值的工具。
好吧...以上是我在论证为什么你应该使用“对于这样一个简单的任务来说似乎真的很复杂”的方法,但如果这不是你的事并且你想混合和匹配系统(哪个使您的代码更复杂)那么您的 disposeBag 想法就可以了。不过用一个袋子装一个一次性的感觉有点奇怪...
正如所承诺的,这里列出了 Apple 让我们推送数据的所有方式:
- 关闭
- target/action(UIControl 又名 IBAction)
- 代表
- 通知(通知中心)
- KVO
- 设置变量(是否 set/will 设置)
- 子分类抽象基础类
- async/await
- 出版商