# Publishers.HandleEvents

**제네릭 구조체** | Publisher의 이벤트가 발생할 때 특정 클로저를 수행하는 Publisher

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

* `upstream` : 상위에 흐르는 Publisher
* `receiveSubscription` : Publisher가 상위 Publisher로부터 구독을 전달받을 때 수행할 클로저. 기본값은 nil
* `receiveOutput` : Publisher가 상위 Publisher로부터 값을 전달받을 때 수행할 클로저. 기본값은 nil
* `receiveCompletion` : Publisher가 상위 Publisher로부터 완료를 전달받을 때 수행할 클로저. 기본값은 nil
* `receiveCancel` : 하위 리시버가 발행을 취소할 때 수행할 클로저. 기본값은 nil
* `receiveRequest` : Publisher가 더 많은 요소를 위해 요청을 전달받을 때 수행할 클로저. 기본값은 nil

스트림의 생명 주기 동안 발생하는 여러 이벤트에서 실행할 액션을 등록한다.

특정 이벤트가 발생할 때 특정 작업을 수행하기 위해 사용할 수 있다.

Publisher의 생명 주기를 이해하기 위해 사용할 수 있다.

`sink`는 Subscriber에 대한 오퍼레이터고, `handleEvents`는 Publisher에 대한 오퍼레이터다.

* `sink`는 Subscriber의 구독에 의해 최종적으로 발행된 이벤트에 대해 동작한다.
* `handleEvents`는 구독에 의해 상위 Publisher가 발행하는 이벤트에 대해 동작한다.

`handleEvents` 오퍼레이터와 관련이 있다.

```swift
// Publishers.HandleEvents Publisher
Publishers
  .HandleEvents(upstream: Just(Void()),
                receiveSubscription: { _ in print("Combine HandleEvents ReceiveSubscription") },
                receiveOutput: { print("Combine HandleEvents ReceiveOutput") },
                receiveCompletion: { _ in print("Combine HandleEvents ReceiveCompletion") },
                receiveCancel: { print("Combine HandleEvents ReceiveCancel") },
                receiveRequest: { _ in print("Combine HandleEvents ReceiveRequest") })
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine HandleEvents Error")
    case .finished:
      print("Combine HandleEvents Finish")
    }
  }, receiveValue: {
    print("Combine HandleEvents")
  })
  .store(in: &cancellables)

// handleEvents Operator
Just(Void())
  .handleEvents(receiveSubscription: { _ in print("Combine HandleEvents ReceiveSubscription") },
                receiveOutput: { print("Combine HandleEvents ReceiveOutput") },
                receiveCompletion: { _ in print("Combine HandleEvents ReceiveCompletion") },
                receiveCancel: { print("Combine HandleEvents ReceiveCancel") },
                receiveRequest: { _ in print("Combine HandleEvents ReceiveRequest") })
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine HandleEvents Error")
    case .finished:
      print("Combine HandleEvents Finish")
    }
  }, receiveValue: {
    print("Combine HandleEvents")
  })
  .store(in: &cancellables)

// Combine HandleEvents Receive Request
// Combine HandleEvents Receive Subscription
// Combine HandleEvents Receive Output
// Combine HandleEvents
// Combine HandleEvents Receive Completion
// Combine HandleEvents Finish
```

결과를 통해 Publisher는 에러를 내지 않는 경우 다음과 같은 순서로 동작한다는 것을 알 수 있다.

1. Publisher : Receive Request
2. Publisher : Receive Subscription
3. Publisher : Receive Output
4. Subscriber : Receive Value
5. Publisher : Receive Completion
6. Subscriber : Receive Finished

## RxSwift

`do` 오퍼레이터를 사용하여 구현할 수 있다.

```swift
Observable.just(Void())
  .do(onNext: { print("RxSwift HandleEvents OnNext") },
      afterNext: { print("RxSwift HandleEvents AfterNext") },
      onError: { _ in print("RxSwift HandleEvents OnError") },
      afterError: { _ in print("RxSwift HandleEvents AfterError") },
      onCompleted: { print("RxSwift HandleEvents OnCompleted") },
      afterCompleted: { print("RxSwift HandleEvents AfterCompleted") },
      onSubscribe: { print("RxSwift HandleEvents OnSubscribe") },
      onSubscribed: { print("RxSwift HandleEvents OnSubscribed") },
      onDispose: { print("RxSwift HandleEvents OnDispose") })
  .subscribe(onNext: {
    print("RxSwift HandleEvents")
  }, onError: { _ in
    print("RxSwift HandleEvents Error")
  }, onCompleted: {
    print("RxSwift HandleEvents Finish")
  })
  .disposed(by: disposeBag)

// RxSwift HandleEvents OnSubscribe
// RxSwift HandleEvents OnNext
// RxSwift HandleEvents
// RxSwift HandleEvents AfterNext
// RxSwift HandleEvents OnCompleted
// RxSwift HandleEvents Finish
// RxSwift HandleEvents AfterCompleted
// RxSwift HandleEvents OnSubscribed
// RxSwift HandleEvents OnDispose
```

## ReactiveSwift

`on` 오퍼레이터를 사용하여 구현할 수 있다.

```swift
SignalProducer(value: Void())
  .on(starting: { print("ReactiveSwift HandleEvents Starting") },
      started: { print("ReactiveSwift HandleEvents Started") },
      event: { _ in print("ReactiveSwift HandleEvents Event") },
      failed: { _ in print("ReactiveSwift HandleEvents Failed") },
      completed: { print("ReactiveSwift HandleEvents Completed") },
      interrupted: { print("ReactiveSwift HandleEvents Interrupted") },
      terminated: { print("ReactiveSwift HandleEvents Terminated") },
      disposed: { print("ReactiveSwift HandleEvents Dispose") },
      value: { print("ReactiveSwift HandleEvents Value") })
  .start { event in
    switch event {
    case .value:
      print("ReactiveSwift HandleEvents")
    case .failed:
      print("ReactiveSwift HandleEvents Error")
    case .completed:
      print("ReactiveSwift HandleEvents Finish")
    default:
      break
    }
  }

// ReactiveSwift HandleEvents Starting
// ReactiveSwift HandleEvents Event
// ReactiveSwift HandleEvents Value
// ReactiveSwift HandleEvents
// ReactiveSwift HandleEvents Event
// ReactiveSwift HandleEvents Completed
// ReactiveSwift HandleEvents Terminated
// ReactiveSwift HandleEvents Finish
// ReactiveSwift HandleEvents Dispose
// ReactiveSwift HandleEvents Started
```

## 참고

[ReactiveX - Operators - Do](http://reactivex.io/documentation/operators/do.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/handleevents.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.
