바닐라 스로틀 가이드
스로틀은 호출이 계속 들어오는 동안 함수의 실행 빈도를 제한합니다. 디바운스와 달리 활동이 멈출 때까지 기다리지 않습니다. 연속 이벤트와 업데이트에 적합한 제한된 실행 간격을 만듭니다.
기본 설정에서는 첫 호출이 즉시 실행됩니다. 대기 기간에 받은 호출은 가장 최근 인수를 사용하는 한 번의 후행 실행으로 통합됩니다.
스로틀의 작동 방식
다음 타임라인은 3틱마다 한 번의 실행을 허용하는 스로틀러를 보여 줍니다.
Throttling (one execution per 3 ticks)
Timeline: [1 second per tick]
Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
Executed: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅
[================================================================]
^ At most one execution per interval
[First burst] [More calls] [Spaced calls]
Execute first Keep latest trailing Execute when allowed
일부 호출은 버려질 수 있지만 활동이 계속되는 동안 예측 가능한 간격으로 실행이 이어집니다.
스로틀을 사용하는 경우
다음과 같은 경우 스로틀을 선택합니다.
- 이벤트가 들어오는 동안 작업이 계속되어야 합니다.
- 실행 사이에 최소 간격을 두어야 합니다.
- 중간 호출을 버려도 됩니다.
- 첫 호출에 대한 즉각적인 피드백이 유용합니다.
다음과 같은 경우 다른 유틸리티를 선택합니다.
- 활동이 멈출 때까지 작업을 기다려야 합니다. 디바운스를 사용합니다.
- 창 안에서 정해진 수의 호출을 실행할 수 있어야 합니다. 요청률 제한을 사용합니다.
- 모든 작업을 최종적으로 실행해야 합니다. 큐를 사용합니다.
- 여러 항목을 함께 실행해야 합니다. 배칭을 사용합니다.
- Promise 결과, 재시도 또는 중단 지원이 필요합니다. 비동기 스로틀을 사용합니다.
TanStack Pacer에서 스로틀 사용하기
TanStack Pacer는 두 가지 코어 스로틀 API를 제공합니다.
throttle은 스로틀된 함수를 반환합니다.Throttler는 생명주기 메서드, 동적 옵션, 콜백, 관찰 가능한 상태를 노출합니다.
편의 함수
스로틀된 함수를 호출하기만 하면 된다면 throttle을 사용합니다.
import { throttle } from '@tanstack/pacer'
const updateScrollPosition = throttle(
(position: number) => {
renderScrollPosition(position)
},
{ wait: 100 },
)
window.addEventListener('scroll', () => {
updateScrollPosition(window.scrollY)
})
클래스 API
대기 중인 작업을 검사하거나 제어해야 한다면 Throttler를 사용합니다.
import { Throttler } from '@tanstack/pacer'
const scrollThrottler = new Throttler(renderScrollPosition, {
wait: 100,
})
scrollThrottler.maybeExecute(120) // Executes immediately.
scrollThrottler.maybeExecute(180) // Becomes the trailing call.
console.log(scrollThrottler.store.state.isPending) // true
throttle이 반환한 함수와 Throttler.maybeExecute()는 모두 void를 반환합니다.
결과 및 오류
동기 스로틀러는 반환 값을 유지하거나 오류를 포착하지 않습니다. 선행 오류는 maybeExecute()에서 전파됩니다. 후행 실행은 나중에 타이머에서 실행되므로 래핑된 함수 안에서 오류를 처리합니다.
호출자가 결과를 기다려야 하거나 유틸리티에서 비동기 오류를 관리해야 한다면 비동기 스로틀을 사용합니다.
실행 타이밍
leading과 trailing 옵션은 스로틀 간격의 어느 에지에서 실행할 수 있는지를 제어합니다.
leading | trailing | 동작 |
|---|---|---|
true | true | 첫 호출은 즉시 실행하고 차단된 가장 최근 호출은 후행 에지에서 실행합니다. 기본값입니다. |
true | false | 허용될 때 즉시 실행하고 간격 중의 호출은 버립니다. |
false | true | 첫 실행을 후행 에지까지 지연하고 간격 중에 받은 가장 최근 인수를 사용합니다. |
false | false | 어떤 호출도 실행하지 않습니다. |
const throttler = new Throttler(updateProgress, {
wait: 1000,
leading: true,
trailing: true,
})
throttler.maybeExecute(10) // Executes immediately.
throttler.maybeExecute(20)
throttler.maybeExecute(30) // Executes at the trailing edge with 30.
기존 간격 중에 받은 호출은 해당 간격을 다시 시작하지 않고 후행 인수를 업데이트합니다. 이것이 디바운스와의 핵심 차이입니다.
대기 중인 작업 제어하기
플러시
flush()는 대기 중인 후행 호출을 즉시 실행합니다. 대기 중인 후행 호출이 없으면 아무 작업도 하지 않습니다.
throttler.maybeExecute(10) // Leading execution.
throttler.maybeExecute(20) // Pending trailing execution.
throttler.flush() // Executes with 20 now.
취소
cancel()은 대기 중인 후행 호출을 버리고 저장된 인수를 지웁니다. 가장 최근에 완료된 실행의 타이밍은 재설정하지 않습니다.
throttler.maybeExecute(20)
throttler.cancel()
재설정
reset()은 상태 카운터와 타이밍 값을 기본값으로 복원합니다. 이미 예약된 시간 제한은 지우지 않습니다. 대기 중인 작업을 버려야 한다면 reset() 전에 cancel()을 호출합니다.
throttler.cancel()
throttler.reset()
런타임에 동작 설정하기
생성 후 옵션을 업데이트하려면 setOptions()를 사용합니다.
throttler.setOptions({
wait: 250,
trailing: false,
})
변경된 wait 값은 기존 후행 시간 제한의 일정을 다시 잡지 않습니다. 이후의 예약과 실행에 적용됩니다.
enabled와 wait 옵션에는 스로틀러 인스턴스를 받는 함수를 지정할 수 있습니다.
const throttler = new Throttler(updateProgress, {
enabled: (throttler) => throttler.store.state.executionCount < 100,
wait: (throttler) =>
throttler.store.state.executionCount < 10 ? 100 : 250,
})
setOptions()를 통해 스로틀러를 비활성화하면 대기 중인 후행 실행이 취소됩니다.
실행 관찰하기
onExecute는 래핑된 함수 이후에 실행되며 실행된 인수와 스로틀러 인스턴스를 차례로 받습니다.
const throttler = new Throttler(updateProgress, {
wait: 100,
onExecute: (args, throttler) => {
console.log('Rendered value:', args[0])
console.log('Executions:', throttler.store.state.executionCount)
},
})
타입 검사를 거친 설정을 여러 인스턴스에서 공유하려면 throttlerOptions()로 정의합니다.
상태
클래스는 throttler.store에 상태를 저장합니다.
애플리케이션이 유지한 일부 상태를 복원하려면 부분 스냅샷을 initialState로 전달합니다. 이 스냅샷은 기본값과 병합됩니다. 지속 가능한 필드만 복원합니다. 대기 중인 타이머는 복원되지 않습니다.
일반적으로 유용한 속성은 다음과 같습니다.
isPending: 후행 실행이 대기 중인지 나타냅니다.lastArgs: 후행 실행 가능성에 대비해 유지한 인수입니다.lastExecutionTime: 래핑된 함수가 마지막으로 실행된 시각입니다.nextExecutionTime: 다음 실행이 가능한 시각입니다.executionCount: 래핑된 함수가 실행된 횟수입니다.status:'disabled','idle'또는'pending'입니다.
전체 옵션과 상태 타입은 Throttler API 레퍼런스를 참고합니다.