# Publishers.Throttle

**제네릭 구조체** | 주어진 시간 내에 상위 Publisher가 발행한 가장 최신 또는 첫 번째 요소를 발행하는 Publisher

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

* `upstream` : 상위에 흐르는 Publisher
* `interval` : 가장 최신의 요소를 찾고 배출할 시간 간격
* `scheduler` : 요소를 발행하는 스케줄러
* `latest` : 가장 최신의 요소를 발행하는지를 가리키는 불리언 값

요소가 배출되고 주어진 시간이 지나고서야 그 시간 내에 배출된 첫 번째 또는 가장 최신의 요소를 발행한다.

`debounce`는 주어진 시간 동안 값을 전달하지 않아야 마지막에 전달된 값을 발행하지만, `throttle`은 주어진 시간이 지날 때 그 시간 내에 배출된 첫 번째 또는 가장 최신의 요소를 발행한다.

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

```swift
let subject = PassthroughSubject<Int, Never>()

// Publishers.Throttle Publisher
Publishers.Throttle(upstream: subject, interval: .seconds(1), scheduler: DispatchQueue.main, latest: true)
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine Throttle Error")
    case .finished:
      print("Combine Throttle Finish")
    }
  }, receiveValue: { value in
    print("Combine Throttle : \(value)")
  })
  .store(in: &cancellables)

// Combine Throttle : 9

// throttle Operator (latest: true)
subject
  .throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine Throttle Error")
    case .finished:
      print("Combine Throttle Finish")
    }
  }, receiveValue: { value in
    print("Combine Throttle : \(value)")
  })
  .store(in: &cancellables)

// Combine Throttle : 9  

// throttle Operator (latest: false)
subject
  .throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: false)
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine Throttle Error")
    case .finished:
      print("Combine Throttle Finish")
    }
  }, receiveValue: { value in
    print("Combine Throttle : \(value)")
  })
  .store(in: &cancellables)

// Combine Throttle : 0  

for i in 0 ..< 10 {
  subject.send(i)
}
```

1과 2의 코드는 값이 발행되면 1초의 카운트를 제어 카운트가 끝나면 해당 시간 내에 발행된 최신의 요소를 발행한다.

3의 코드는 값이 발행되면 1초의 카운트를 제어 카운트가 끝나면 해당 시간 내에 발행된 첫 번째 요소를 발행한다.

코드를 실행하면 반복문을 통해 0부터 9까지 `subject`에 값을 전달하는데, 이 동작이 1초 안에 모두 이루어지므로 카운트가 끝날 때 스트림의 첫 번째 값은 0, 최신 값은 9일 것이다.

> 현재 런타임 에러가 발생하여 실제 동작을 확인할 수 없다. [포럼](https://forums.swift.org/t/exc-bad-instruction-with-combine-throttle/28850)

## RxSwift

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

카운트의 시작을 불러 일으키는 첫 번째 값과 카운트가 끝날 때의 최신 값을 모두 배출하는 것으로 구현되어 있다.

```swift
let subject = PublishSubject<Int>()

subject
  .throttle(.seconds(1), scheduler: MainScheduler.instance)
  .subscribe(onNext: { value in
    print("RxSwift Throttle : \(value)")
  }, onError: { _ in
    print("RxSwift Throttle Error")
  }, onCompleted: {
    print("RxSwift Throttle Finish")
  })
  .disposed(by: disposeBag)

for i in 0 ..< 10 {
  subject.onNext(i)
}

// RxSwift Throttle : 0
// RxSwift Throttle : 9
```

## ReactiveSwift

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

```swift
let property = MutableProperty<Int>(0)

property.signal
  .throttle(1, on: QueueScheduler.main)
  .observe { event in
    switch event {
    case let .value(value):
      print("ReactiveSwift Throttle : \(value)")
    case .failed:
      print("ReactiveSwift Throttle Error")
    case .completed:
      print("ReactiveSwift Throttle Finish")
    default:
      break
    }
}

for i in 0 ..< 10 {
  property.value = i
}

// ReactiveSwift Throttle : 9
```

## 참고

[Publishers.Debounce](/combine-rxswift-reactiveswift/publisher/debounce.md)


---

# 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/throttle.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.
