Насколько я понимаю, причина использования .asSingle
в RxSwift заключается в том, что когда вы подписываетесь, ваш подписчик получает SingleEvent
, который либо .success(value)
, либо .error(error)
. Таким образом, вашему подписчику не нужно беспокоиться о получении события типа .completion
, потому что его нет.
Этого не существует в Combine. В Combine, с точки зрения подписчика, Future
- это просто еще один тип Publisher
, который может выдавать выходные значения и .finished
или .failure(error)
. Система типов не навязывает тот факт, что Future
никогда не испускает .finished
.
. Из-за этого не существует программной c причины для конкретного возврата Future
. Вы можете утверждать, что при возврате Future
документируется ваше намерение всегда возвращать либо только один вывод, либо ошибку. Но это не меняет способ написания вашего подписчика.
Более того, из-за интенсивного использования обобщений Combine, как только вы захотите применить какой-либо оператор к Future
, у вас нет будущее больше. Если вы примените map
к некоторому Future<V, E>
, вы получите Map<Future<V, E>, V2>
и аналогичное значение для любого другого оператора. Типы быстро выходят из-под контроля и скрывают тот факт, что внизу есть Future
.
Если вы действительно хотите, вы можете реализовать свой собственный оператор для преобразования любого Publisher
в Future
, Но вам придется решить, что делать, если восходящий поток испускает .finished
, поскольку Future
не может испускать .finished
.
extension Publisher {
func asFuture() -> Future<Output, Failure> {
return Future { promise in
var ticket: AnyCancellable? = nil
ticket = self.sink(
receiveCompletion: {
ticket?.cancel()
ticket = nil
switch $0 {
case .failure(let error):
promise(.failure(error))
case .finished:
// WHAT DO WE DO HERE???
fatalError()
}
},
receiveValue: {
ticket?.cancel()
ticket = nil
promise(.success($0))
})
}
}
}