Debounced эффекты
Debounced effects позволяют отложить асинхронную операцию до паузы в потоке событий. Типичные сценарии — поиск при вводе пользователя и автосохранение формы.
Примеры reducer-ов на этой странице написаны в стиле Immer: они мутируют draft
stateи предполагают, чтоMachineManagerсоздан сimmerMiddleware. Без middleware reducer должен вернуть новый объект{ state, context }.
Концепция debounce
Функция debounce откладывает выполнение до тех пор, пока после последнего вызова не пройдёт заданный интервал. Используйте debounce, когда:
- Обработка каждого события требует значительных ресурсов
- Результат промежуточных вызовов не имеет значения
- Важен только результат последнего вызова
Создание debounced эффекта
Библиотека lite-fsm не содержит собственной реализации debounce. Используйте готовую функцию, например debounce из lodash, или передайте собственную реализацию:
import { createMachine } from "@lite-fsm/core";
import { debounce } from "lodash";
const initialContext = {
pagination: { limit: 20, offset: 0 },
results: [] as unknown[],
};
const runSearch = async ({ query, api, transition }) => {
const response = await api.search({ query });
transition({
type: "SEARCH_RESOLVE",
payload: { response },
});
};
const debouncedSearch = debounce(runSearch, 250);
export const onboardingSearch = createMachine({
config: {
IDLE: {
SET_SEARCH_INPUT: "SEARCH_PENDING",
SEARCH_RESOLVE: null,
SEARCH_REJECT: null,
},
SEARCH_PENDING: {
SEARCH_STARTED: "IDLE",
},
},
initialState: "IDLE",
initialContext,
reducer: (state, action, { nextState }) => {
state.state = nextState;
if (action.type === "SEARCH_RESOLVE") {
state.context.results = action.payload.response.items;
}
},
effects: {
SEARCH_PENDING: (deps) => {
// 1) сразу возвращаем автомат в IDLE, чтобы следующий ввод снова попал в SEARCH_PENDING
deps.transition({ type: "SEARCH_STARTED" });
// 2) сам поиск откладываем через debounce
debouncedSearch({ ...deps, query: deps.action.payload.query });
},
},
});Важность промежуточного состояния
В приведённом примере переход SEARCH_STARTED возвращает автомат в состояние IDLE. Это важно для работы debounced effect в модели, где effects запускаются при входе в состояние:
-
Активация effect перед debounce: если оставаться в
SEARCH_PENDING, effect будет вызван только при первом входе в состояние. Быстрый возврат вIDLEпозволяет снова войти вSEARCH_PENDINGпри каждом новом событии. -
Сохранение результата debounce: хотя автомат возвращается в
IDLE, отложенная функция продолжает ждать окончания таймера debounce и затем выполняется.
Без промежуточного перехода debounce будет запускаться не на каждый ввод, потому что effects в lite-fsm привязаны к входу в состояние, а не к событию как таковому.