# Future

**제네릭 클래스** | 결국에는 하나의 값을 낸 후 종료하거나 실패하는 Publisher

이니셜라이저는 한 개의 인자를 받는다.

* `attemptToFulfill` : Publisher가 요소를 배출하거나 에러로 종료할 때 Publisher가 호출하는 `Future.Promise`

Future는 `Future.Promise`라는 타입 별칭으로 클로저를 제공한다. 이 클로저는 Result 타입의 인자를 하나 받고 반환값이 없는 형태다.

이 클로저를 사용하여 Future의 이니셜라이저로 넘어가는 클로저에서 어떠한 작업을 수행하고 성공했을 때의 값이나 실패했을 때의 에러를 `Future.Promise` 클로저로 전달한다.

결국 Future는 어떠한 작업을 수행한 후 하나의 값을 낸 후 종료하거나 실패한다.

```swift
Future<Void, Error> { promise in
  // 1
  promise(.success(Void()))
  // 2
  promise(.failure(error))
}
.sink(receiveCompletion: { completion in
  switch completion {
  case .failure:
    print("Combine Future Error")
  case .finished:
    print("Combine Future Finish")
  }
}, receiveValue: {
  print("Combine Future")
})
.store(in: &cancellables)

// Combine Future
// Combine Future Finish
```

Future는 하나의 값을 낸 후 종료하거나 실패한다.

1의 코드가 실행되면 값을 내므로 Publisher는 종료한다. 그렇기 때문에 2의 코드는 효력이 없게 된다.

```swift
Future<Void, Error> { promise in
  // 1
  promise(.failure(error))
  // 2
  promise(.success(Void()))
}
.sink(receiveCompletion: { completion in
  switch completion {
  case .failure:
    print("Combine Future Error")
  case .finished:
    print("Combine Future Finish")
  }
}, receiveValue: {
  print("Combine Future")
})
.store(in: &cancellables)

// Combine Future Error
```

마찬가지로 1의 코드를 실행하면 에러를 내므로 Publisher는 에러를 낸다.

그렇기 때문에 2의 코드는 효력이 없게 된다.

## RxSwift

Single을 사용하여 구현할 수 있다.

```swift
Single<Void>.create { observer in
  observer(.success(Void()))
  // 에러를 내는 경우 위의 코드 대신 다음과 같이 작성한다.
  // observer(.failure(error))
  return Disposables.create()
}
.subscribe(onSuccess: { print("RxSwift Future") })
.disposed(by: disposeBag)

// RxSwift Future
```

## ReactiveSwift

해당 동작을 구현하기 위한 오퍼레이터를 제공하지 않는다.

## 참고

[Combine's Future](https://www.thomasvisser.me/2019/07/06/combine-future/)

[ReactiveX - Operator - Create](http://reactivex.io/documentation/operators/create.html)

[ReactiveX - Single](http://reactivex.io/documentation/single.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://presto95.gitbook.io/combine-rxswift-reactiveswift/publisher/future.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
