想象一下,我有一个使用PassthroughSubject
来接收其输入的类的API:
class Logger {
let log: PassthroughSubject<String, Never>
}
通常,我可以通过调用logger.log.send("test")
来发出值。
现在说我想在这个通用记录器和我的代码之间有一个自己的记录器:
class MyLogger {
let log: PassthroughSubject<String, Never>
}
这应该在字符串前面加上前缀,然后将所有更新发送到Logger。有没有办法将一个PassthroughSubject(例如MyLogger)的输出链接到另一个(例如Logger)的输出?
我知道我可以这样:
let cancellable = myLogger.log.sink {
logger.log.send("[MyApp] " + $0)
}
但是,这似乎不是将事物链接在一起的组合方式。我希望有一个可以使用与此类似的API:
logger.log.subscribe(myLogger.log.map { "[MyApp] " + $0 })
但是,由于我认为地图导致地图变成了发布者而不是主题,因此无法编译:
实例方法“订阅”要求“ Publishers.Map
,字符串>”符合“主题”
除了依赖sink
之外,是否还有一种更具说明性的API,可以使一个PassthroughSubject订阅另一个PassthroughSubject的更新(支持它们之间的突变)?
答案 0 :(得分:0)
如果您翻转订阅的顺序,它将起作用:
let cancellable = myLogger.log
.map { "[MyApp] " + $0 }
.subscribe(logger.log)
myLogger.send("test") // will send "[MyApp] test" to logger.log
话虽这么说,用Combine对这样的set 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)
}
}