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>,这并不令人满意。