TimeoutManager
TimeoutManager는 TanStack Query에서 setTimeout 및 setInterval 타이머를 처리합니다.
TanStack Query는 타이머를 사용해 쿼리 staleTime 및 gcTime 같은 기능뿐만 아니라 재시도, 스로틀링, 디바운싱도 구현합니다.
기본적으로 TimeoutManager는 전역 setTimeout 및 setInterval을 사용하지만, 대신 사용자 지정 구현을 사용하도록 구성할 수 있습니다.
사용 가능한 메서드는 다음과 같습니다:
timeoutManager.setTimeoutProvidertimeoutManager.setTimeouttimeoutManager.clearTimeouttimeoutManager.setIntervaltimeoutManager.clearInterval
timeoutManager.setTimeoutProvider
setTimeoutProvider를 사용하여 setTimeout, clearTimeout, setInterval, clearInterval 함수의 사용자 지정 구현인 TimeoutProvider를 설정할 수 있습니다.
수천 개의 쿼리로 인해 이벤트 루프 성능 문제가 발생하는 경우 유용할 수 있습니다. 사용자 지정 TimeoutProvider는 전역 setTimeout의 최대 지연 값인 약 24일보다 긴 타이머 지연도 지원할 수 있습니다.
애플리케이션의 모든 timer에 동일한 provider가 일관되게 사용되도록 QueryClient 또는 쿼리를 생성하기 전에 setTimeoutProvider를 호출하는 것이 중요합니다. 서로 다른 TimeoutProviders는 상대방의 timer를 취소할 수 없기 때문입니다.
import { timeoutManager, QueryClient } from '@tanstack/react-query'
import { CustomTimeoutProvider } from './CustomTimeoutProvider'
timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())
export const queryClient = new QueryClient()
TimeoutProvider
타이머는 성능에 매우 민감합니다. 단기 타이머(예: 지연 시간이 5초 미만인 타이머)는 지연 시간에 민감한 경향이 있는 반면, 장기 타이머는 타이머 병합, 즉 마감 시간이 비슷한 타이머를 계층적 타임 휠 같은 데이터 구조를 사용해 함께 일괄 처리하는 방식에서 더 큰 이점을 얻을 수 있습니다.
NodeJS 같은 런타임은 전역 setTimeout 및 setInterval 함수에서 객체를 반환하므로, TimeoutProvider 타입은 구현에서 Symbol.toPrimitive을 통해 number로 변환할 수 있는 타이머 ID 객체를 처리하도록 요구합니다. TimeoutProvider 구현은 내부적으로 타이머 ID를 숫자로 강제 변환하거나 { [Symbol.toPrimitive]: () => number }을 구현하는 자체 사용자 지정 객체 타입을 자유롭게 반환할 수 있습니다.
type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }
type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> = {
readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId
readonly clearTimeout: (timeoutId: TTimerId | undefined) => void
readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId
readonly clearInterval: (intervalId: TTimerId | undefined) => void
}
timeoutManager.setTimeout
setTimeout(callback, delayMs)은 전역 setTimeout 함수처럼 약 delay밀리초 후에 실행되도록 콜백을 예약합니다.콜백은 timeoutManager.clearTimeout으로 취소할 수 있습니다.
타이머 ID를 반환하며, 이는 숫자이거나 Symbol.toPrimitive을 통해 숫자로 강제 변환할 수 있는 객체일 수 있습니다.
import { timeoutManager } from '@tanstack/react-query'
const timeoutId = timeoutManager.setTimeout(
() => console.log('ran at:', new Date()),
1000,
)
const timeoutIdNumber: number = Number(timeoutId)
timeoutManager.clearTimeout
clearTimeout(timerId)은 전역 clearTimeout 함수처럼 setTimeout으로 예약된 타임아웃 콜백을 취소합니다. timeoutManager.setTimeout이 반환한 타이머 ID를 인수로 전달하여 호출해야 합니다.
import { timeoutManager } from '@tanstack/react-query'
const timeoutId = timeoutManager.setTimeout(
() => console.log('ran at:', new Date()),
1000,
)
timeoutManager.clearTimeout(timeoutId)
timeoutManager.setInterval
setInterval(callback, intervalMs)은 전역 setInterval 함수처럼 약 intervalMs마다 콜백이 호출되도록 예약합니다.
setTimeout과 마찬가지로 타이머 ID를 반환하며, 이는 숫자이거나 Symbol.toPrimitive를 통해 숫자로 강제 변환할 수 있는 객체일 수 있습니다.
import { timeoutManager } from '@tanstack/react-query'
const intervalId = timeoutManager.setInterval(
() => console.log('ran at:', new Date()),
1000,
)
timeoutManager.clearInterval
clearInterval(intervalId)은 전역 clearInterval 함수처럼 인터벌을 취소하는 데 사용할 수 있습니다. timeoutManager.setInterval이 반환한 인터벌 ID를 인자로 전달해 호출해야 합니다.
import { timeoutManager } from '@tanstack/react-query'
const intervalId = timeoutManager.setInterval(
() => console.log('ran at:', new Date()),
1000,
)
timeoutManager.clearInterval(intervalId)