Swift: 在 Publisher 上有条件地执行一个操作
Swift: execute an operation conditionally on Publisher
我正在使用 Combine 进行网络连接,我想仅在特定条件存在时才执行某些组合操作,例如,如果本地布尔变量 needsDecoding
为真,我想添加 .decode(type:,decoder:)
:
if (needsDecoding) {
return URLSession.shared.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: T.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
} else {
return URLSession.shared.dataTaskPublisher(for: request)
.map(\.data)
.eraseToAnyPublisher()
}
上面的代码有效,但是否可以有条件地将 .decode()
添加到链中?
暂时假设我们尝试编写一个通用函数来做同样的事情,接受一些数据并且 returns 要么是通用的解析类型,要么是原始数据:
func conditionallyDecodeSomeData<T>(data:Data) -> What_Goes_Here? {
...
}
您的问题与“此功能应该是什么类型 return”非常相似。答案是作为所有可能结果的最一般超集的类型。那可能是 Any
。 (虽然你希望它在 Result
monad 中,所以它可能是 Result<Any, Error>
)。使用 Any
可以,但它非常糟糕 'code smell'
如果您的 return 类型数量有限,那么您可以创建一个枚举类型:
enum OperationResults {
case justData(Data)
case oneParsedResult(Result1)
case anotherParsedResult(AnotherResult)
}
然后您的 Combine 管道可以生成 AnyPublisher<OperationResults, Error>
。但是,如果您想要真正通用的东西,那么您可能不得不使用 AnyPublisher<Any, Error>
,这并不令人满意。
我正在使用 Combine 进行网络连接,我想仅在特定条件存在时才执行某些组合操作,例如,如果本地布尔变量 needsDecoding
为真,我想添加 .decode(type:,decoder:)
:
if (needsDecoding) {
return URLSession.shared.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: T.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
} else {
return URLSession.shared.dataTaskPublisher(for: request)
.map(\.data)
.eraseToAnyPublisher()
}
上面的代码有效,但是否可以有条件地将 .decode()
添加到链中?
暂时假设我们尝试编写一个通用函数来做同样的事情,接受一些数据并且 returns 要么是通用的解析类型,要么是原始数据:
func conditionallyDecodeSomeData<T>(data:Data) -> What_Goes_Here? {
...
}
您的问题与“此功能应该是什么类型 return”非常相似。答案是作为所有可能结果的最一般超集的类型。那可能是 Any
。 (虽然你希望它在 Result
monad 中,所以它可能是 Result<Any, Error>
)。使用 Any
可以,但它非常糟糕 'code smell'
如果您的 return 类型数量有限,那么您可以创建一个枚举类型:
enum OperationResults {
case justData(Data)
case oneParsedResult(Result1)
case anotherParsedResult(AnotherResult)
}
然后您的 Combine 管道可以生成 AnyPublisher<OperationResults, Error>
。但是,如果您想要真正通用的东西,那么您可能不得不使用 AnyPublisher<Any, Error>
,这并不令人满意。