假设我有一个API,用于使用PassthroughSubject
接收其输入的类:
class Logger {
let log: PassthroughSubject<String, Never>
}
通常,我可以通过调用logger.log.send("test")
来发出一个值。
现在说我想有我自己的记录器,它位于这个通用记录器和我的代码之间:
class MyLogger {
let log: PassthroughSubject<String, Never>
}
这应该作为字符串的前缀,然后将任何更新发送到Logger。是否有方法将输出从一个PassthroughSubject(例如MyLogger(链接到另一个PassthroughSubject(如Logger(?
我知道我可以这样做:
let cancellable = myLogger.log.sink {
logger.log.send("[MyApp] " + $0)
}
然而,这似乎不像是将事物链接在一起的联合方式。我希望有一个API我可以使用更类似于这个:
logger.log.subscribe(myLogger.log.map { "[MyApp] " + $0 })
然而,这并没有编译,因为我认为地图导致它变成了一个出版商,而不是一个主题:
实例方法"subscribe"需要"Publishers"。映射<PassthroughSubject<字符串,从不>,字符串>'符合"主题">
除了依赖sink
之外,是否还有一种更具声明性的API可以让一个PassthroughSubject订阅来自另一个的更新(支持其间的突变(?
如果您翻转订阅的顺序,它会起作用:
let cancellable = myLogger.log
.map { "[MyApp] " + $0 }
.subscribe(logger.log)
myLogger.send("test") // will send "[MyApp] test" to logger.log
话虽如此,像这样使用Combine建模集API似乎有点奇怪,而且Failure
数据类型似乎被完全忽略了。例如,如果日志失败,则无法在失败的链上进行备份通信。
一个更好的API可能是一个正常的函数,它返回一个AnyPublisher
:
class Logger {
func log(_ string: String) -> AnyPublisher<Void, Never>
}
class MyLogger {
func log(_ string: String) -> AnyPublisher<Void, Never> {
return logger.log(string)
}
}