본문으로 건너뛰기

함수: createAsyncDebouncer()

function createAsyncDebouncer<TFn, TSelected>(
fn,
options,
selector): SolidAsyncDebouncer<TFn, TSelected>;

정의 위치: solid-pacer/src/async-debouncer/createAsyncDebouncer.ts:175

비동기 함수의 실행을 지연하는 AsyncDebouncer 인스턴스를 생성하는 저수준 Solid 훅입니다.

유연하고 상태 관리 방식에 구애받지 않도록 설계되었습니다. 디바운서 인스턴스만 반환하므로 createSignal 등 원하는 상태 관리 솔루션과 통합할 수 있습니다.

비동기 디바운스는 마지막 호출 후 지정된 지연 시간이 지나야 비동기 함수가 실행되도록 합니다. 새 호출이 발생할 때마다 지연 타이머가 초기화됩니다. 창 크기 조정이나 입력 변경처럼 이벤트 발생이 멈춘 뒤에만 핸들러를 실행하려는 빈번한 이벤트를 처리할 때 유용합니다.

일정한 간격으로 실행을 허용하는 스로틀과 달리 디바운스는 지정된 지연 시간 동안 함수 호출이 멈출 때까지 모든 실행을 막습니다.

비동기가 아닌 Debouncer와 달리 이 비동기 버전은 디바운스된 함수의 값을 반환할 수 있습니다. 따라서 디바운스된 함수 안에서 결과를 상태 변수에 설정하는 대신 maybeExecute 호출 결과를 사용하려는 API 호출 및 기타 비동기 작업에 적합합니다.

오류 처리:

  • onError 핸들러를 제공하면 오류 및 디바운서 인스턴스와 함께 호출됩니다.
  • throwOnError가 true이면(onError 핸들러가 없을 때의 기본값) 오류가 발생합니다.
  • throwOnError가 false이면(onError 핸들러가 있을 때의 기본값) 오류가 처리된 것으로 간주됩니다.
  • onError와 throwOnError를 함께 사용할 수 있으며, 오류가 발생하기 전에 핸들러가 호출됩니다.
  • 내부 AsyncDebouncer 인스턴스를 사용해 오류 상태를 확인할 수 있습니다.

상태 관리와 셀렉터

훅은 반응형 상태 관리에 TanStack Store를 사용합니다. 다음 두 가지 방식으로 상태 변경을 구독할 수 있습니다. 구독 방식은 다음과 같습니다.

1. debouncer.Subscribe 컴포넌트 사용(컴포넌트 트리 구독에 권장)

Subscribe 컴포넌트를 사용하면 컴포넌트 트리 깊은 곳에서 상태 변경을 구독하면서도 훅에 셀렉터를 전달할 필요가 없습니다. 자식 컴포넌트에서 상태를 구독하려는 경우에 적합합니다.

2. selector 매개변수 사용(훅 수준 구독)

selector 매개변수로 반응형 업데이트를 트리거할 상태 변경을 지정할 수 있으며, 훅 수준에서 관련 없는 상태가 변경될 때 불필요한 업데이트를 방지하여 성능을 최적화합니다.

기본적으로 반응형 상태 구독은 없습니다. 반응형 상태를 추적하려면 셀렉터 함수를 제공하여 셀렉터 함수를 제공하거나 Subscribe 컴포넌트를 사용해 명시적으로 활성화해야 합니다. 이를 통해 불필요한 업데이트를 방지하고 컴포넌트가 상태 변경을 추적할 시점을 완전히 제어할 수 있습니다.

사용할 수 있는 상태 속성은 다음과 같습니다.

  • canLeadingExecute: 디바운서가 선행 에지에서 실행될 수 있는지 여부
  • executionCount: 완료된 함수 실행 횟수
  • hasError: 마지막 실행에서 오류가 발생했는지 여부
  • isPending: 디바운서가 타임아웃 후 실행되기를 기다리고 있는지 여부
  • isExecuting: 현재 비동기 함수 실행이 진행 중인지 여부
  • lastArgs: 가장 최근 maybeExecute 호출에 전달된 인수
  • lastError: 가장 최근 실패한 실행의 오류(있는 경우)
  • lastResult: 가장 최근에 성공한 실행 결과
  • status: 현재 실행 상태('disabled' | 'idle' | 'pending' | 'executing')

언마운트 동작

기본적으로 소유 컴포넌트가 마운트 해제되면 대기 중인 실행을 취소하고 진행 중인 실행을 중단합니다. getAbortSignal()의 중단 신호를 내부 작업(예: fetch)에 전달한 경우에만 Abort가 해당 작업을 취소합니다. onUnmount 옵션으로 이 동작을 사용자 지정할 수 있습니다. 예를 들어 대기 중인 작업을 대신 플러시하려면 다음과 같이 설정합니다.

const debouncer = createAsyncDebouncer(fn, {
wait: 500,
onUnmount: (d) => d.flush()
});

참고: 비동기 유틸리티에서 flush()는 Promise를 반환하며 정리 과정에서는 실행 후 결과를 기다리지 않습니다. debounced 함수가 Solid 시그널을 업데이트하면 해당 업데이트는 컴포넌트가 마운트 해제된 후 실행될 수 있으며 예상치 못한 반응형 업데이트가 발생할 수 있습니다. 따라서 onUnmount에서 flush를 사용할 때는 콜백을 적절히 보호해야 합니다.

타입 매개변수

TFn

TFn extends AnyAsyncFunction

TSelected

TSelected = { }

매개변수

fn

TFn

options

SolidAsyncDebouncerOptions&lt;TFn, TSelected>

selector

(state) => TSelected

반환값

SolidAsyncDebouncer&lt;TFn, TSelected>

예시

// Default behavior - no reactive state subscriptions
const { maybeExecute } = createAsyncDebouncer(
async (query: string) => {
const results = await api.search(query);
return results;
},
{ wait: 500 }
);

// Opt-in to track isPending or isExecuting changes (optimized for loading states)
const debouncer = createAsyncDebouncer(
async (query: string) => {
const results = await api.search(query);
return results;
},
{ wait: 500 },
(state) => ({ isPending: state.isPending, isExecuting: state.isExecuting })
);

// Opt-in to track error state changes (optimized for error handling)
const debouncer = createAsyncDebouncer(
async (searchTerm) => {
const data = await searchAPI(searchTerm);
return data;
},
{
wait: 300,
leading: true, // Execute immediately on first call
trailing: false, // Skip trailing edge updates
onError: (error) => {
console.error('API call failed:', error);
}
},
(state) => ({ hasError: state.hasError, lastError: state.lastError })
);

// Access the selected state (will be empty object {} unless selector provided)
const { isPending, isExecuting } = debouncer.state();