Ответ
Future в Combine — это издатель (Publisher), который представляет собой одноразовую асинхронную операцию. Он выдает либо одно значение (Output), либо ошибку (Failure), после чего завершает работу.
Основное назначение: Обертка существующих асинхронных callback-функций (например, сетевых запросов, операций с базой данных) в реактивную модель Combine.
Пример: Обертка сетевого запроса
func fetchUser(id: Int) -> Future<User, Error> {
Future { promise in
// Асинхронная операция
URLSession.shared.dataTask(with: userURL) { data, _, error in
if let error = error {
promise(.failure(error))
} else if let data = data {
do {
let user = try JSONDecoder().decode(User.self, from: data)
promise(.success(user))
} catch {
promise(.failure(error))
}
}
}.resume()
}
}
// Использование
var cancellables = Set<AnyCancellable>()
fetchUser(id: 123)
.sink(receiveCompletion: { completion in
switch completion {
case .finished: print("Завершено")
case .failure(let error): print("Ошибка: ", error)
}
}, receiveValue: { user in
print("Получен пользователь: ", user.name)
})
.store(in: &cancellables)
Ключевые особенности:
- Однократное выполнение:
Futureзапускает свою работу сразу при подписке и не повторяет её. - Кэширование результата: Если на один
Futureподписываются несколько раз, он выполнит работу один раз, а результат отправит всем подписчикам. - Отмена: Отмена подписки через
cancellablesпредотвратит получение результата, но не отменит саму выполняемую операцию (например, сетевой запрос). Для отмены операции нужна дополнительная логика.
Альтернативы и сравнение:
Just: Издатель, который немедленно выдает одно значение и завершается. Не выполняет асинхронной работы.Deferred: Позволяет отложить создание издателя до момента подписки, что полезно для создания новыхFutureдля каждой подписки.