Проверяет понимание отмены устаревших асинхронных запросов и выбора между Redux-Saga и Redux-Thunk для предотвращения гонок.
Гонка запросов возникает, когда пользователь быстро меняет параметры (например, вводит поисковый запрос), и ответы приходят не в том порядке, в котором были отправлены. В результате на экране может оказаться устаревший результат. Оба подхода решают эту проблему, но по-разному.
takeLatest — это эффект, который запускает сагу на каждый экшен, но при появлении нового экшена того же типа автоматически отменяет предыдущую запущенную сагу. Отмена происходит на уровне генератора: все вложенные эффекты (call, put, fork) прерываются, а промисы, если они поддерживают отмену, отменяются.
import { takeLatest, call, put } from 'redux-saga/effects';
function* fetchUser(action) {
const user = yield call(api.getUser, action.payload);
yield put({ type: 'USER_SUCCESS', payload: user });
}
function* watchFetchUser() {
yield takeLatest('USER_REQUEST', fetchUser);
}
Здесь достаточно одного takeLatest — и все предыдущие запросы отменяются автоматически. Никакого ручного управления контроллерами не нужно.
В thunk отмена реализуется вручную: нужно создать AbortController, передать его signal в fetch/axios, сохранить контроллер (например, в замыкании или в store) и вызвать abort() при новом запросе.
let controller;
export const fetchUser = (id) => async (dispatch) => {
if (controller) controller.abort();
controller = new AbortController();
try {
const res = await fetch(`/api/user/${id}`, { signal: controller.signal });
const data = await res.json();
dispatch({ type: 'USER_SUCCESS', payload: data });
} catch (e) {
if (e.name !== 'AbortError') throw e;
}
};
Код работает, но управление отменой размазано по thunk-функциям, легко забыть вызвать abort или неправильно обработать AbortError.
Если в проекте уже есть redux-saga и много сложных асинхронных сценариев (отмена, retry, параллельные запросы, debounce), takeLatest — естественный выбор. Если проект небольшой и используется только thunk, AbortController справится, но потребует дисциплины и шаблонного кода.
Итог: takeLatest выигрывает за счёт декларативности и централизации логики отмены, тогда как thunk с AbortController — более низкоуровневое и ручное решение, уместное в простых приложениях без саг.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию