如何制作一个在组合中发送多个值的发布者
Posted
技术标签:
【中文标题】如何制作一个在组合中发送多个值的发布者【英文标题】:How to make a Publisher that sends multiple values in Combine 【发布时间】:2021-11-05 11:24:17 【问题描述】:您能帮我解决合并问题吗?
我想创建一个在其生命周期内发送多个值的发布者。更详细地说,我想将带有完成处理程序的方法包装到发布者中,并且完成处理程序应该被多次调用。例如,它是一种用于通过 WebSocket 接收消息的方法,如下所示:
webSocketClient.receiveMessage message, error in
// this closure is called multiple times, everytime a message comes
...
如何将其包装到 Publisher 中?最后我想要AnyPublisher<String, Error>
这样的东西。
当我使用其他 FRP 库时,包装这些非常容易。例如,在 ReactiveSwift 中,可以使用SignalProducer.init(_ startHandler:)
来实现。在 RxSwift 中,它是 Observable.create
方法。
在Combine 中,我发现Future
可以在只有一个值要发出时使用,但它不适合我目前的情况。对于这个用例,我找不到 Publisher 的任何初始化程序。
另外,我在 TCA(可组合架构)中找到了可用于这种情况的 Effect.run。似乎在其实现中使用了自定义发布者,这对于简单的使用来说似乎有点复杂,但这是唯一的方法吗?还有其他简单的方法可以实现类似的行为吗?
我觉得这是一个很常见的场景,所以我想知道Combine用户在实践中是如何处理这种情况的。
提前谢谢你!
【问题讨论】:
【参考方案1】:基本上有两种选择。
在 SwiftUI 环境中,使包含代码的类符合 ObservableObject
并添加 @Published
属性
class ViewModel : ObservableObject
@Published var message = ""
func loadData()
webSocketClient.receiveMessage message, error in
self.message = message
...
在视图中创建视图模型的@StateObject
以接收有关新消息的通知。
或者用send
值声明一个主题
class ViewModel
let subject = PassthroughSubject<String,Never>()
func loadData()
webSocketClient.receiveMessage message, error in
self.subject.send(message)
...
要接收通知获取类的实例,请在主题上调用 sink
并将结果存储到强引用中。
【讨论】:
我明白了。我可以理解,通过引入主题或其他变量是可能的。但是,不引入它们是否可以? 例如,在 RxSwift 中,可以像这样不引入另一个变量。这在Combine中不可能吗?swift let observable = Observable.create observer in webSocketClient.receiveMessage message, error in observer.on(.next(message)) ...
let observable =...
也是一个变量。
不必如此。 Observable.create ....subscribe ...
也是可能的。以上是关于如何制作一个在组合中发送多个值的发布者的主要内容,如果未能解决你的问题,请参考以下文章
在graphql中,组合多个源中的字段共享一个共同值的多个源的最佳方法是啥?