Я использую redux-saga
и @reduxjs/toolkit
. Я делаю несколько запросов к веб-сервису и сохраняю их ответы в redux, и следую шаблону «ожидание/успех/неудача», который упоминался в нескольких местах. Для моей саги о редуксе:
export default function* rootSaga() {
yield takeEvery(actionGetData.toString(), handleGetData);
}
с моей функцией генератора:
function* handleGetData(action: any): Generator<any, any, any> {
yield put({ type: 'ACTION.GETDATA_PENDING', payload: action.payload });
try {
const response = yield call(apiRequest);
const responseData = response.data;
yield put({ type: 'ACTION.GETDATA_FULFILLED', payload: { name: action.payload, data: responseData } });
} catch (error: any) {
yield put({ type: 'ACTION.GETDATA_FAILED', payload: { name: action.payload, data: error.message } });
}
}
Я сохраняю этот статус (ожидание, успех, сбой) в redux, и на экране появляется визуальный компонент, соответствующий этому статусу — анимация загрузки, уведомление об успехе/неуспехе и т. д.
Все это прекрасно работает, но проблема в том, что когда это apiRequest
занимает некоторое время и пользователь преждевременно отменяет запрос, скажем, закрыв страницу до того, как запрос веб-сервиса вернет ответ. В этом случае, когда пользователь перезагружает страницу, статус зависает в состоянии «загрузка», за исключением того, что на этот раз apiRequest
не будет установлено, поэтому нет возможности выйти из этого состояния с успехом или неудачей, поэтому никогда Пользователю отображается анимация окончания загрузки, и нет ничего, что могло бы повторить запрос веб-сервиса.
Как я могу это решить? Есть ли способ вызвать функцию очистки, которая может быть выполнена до завершения функции (например, немедленно вызвать действие «сбой», если страница преждевременно остановлена)? Есть ли способ «просмотреть» этот «ожидающий» статус и вызвать повторную попытку, если он завис на определенное время?
Я вижу, что Тайлер отредактировал/удалил субъективно значимые части вашего сообщения, но оно все еще слишком широкое/открытое. Вы уже пробовали что-нибудь конкретное? Я решил аналогичную проблему в предыдущем проекте, отслеживая все активные сетевые запросы с помощью очереди. Когда запросы удовлетворяются, они удаляются из очереди. Магазин Redux был сохранен в долгосрочном хранилище, например. localStorage, и когда приложение запускается/монтируется, одно из первых действий, которое оно делает, — это выполнение очереди. Это всего лишь один из способов решения проблемы. Скорее всего, в вашем распоряжении есть несколько решений.
@DrewReese Итак, где вы размещаете вызов для выполнения очереди? Я уже отслеживаю сетевые запросы, но моя проблема заключается в том, как определить, когда запросы ожидаются слишком долго, и, например, выждите их и подведите их.
Я реализовал обработку очереди при монтировании приложения и периодически с интервалом примерно в 15 минут. Я использовал Redux-Toolkit-Query (с тайм-аутами и повторными попытками), если вызов конечной точки был успешным, то все хорошо, но если время ожидания истекло/ошибка/и т. д., я бы добавил данные запроса, конечную точку и т. д. в очередь, которая будет периодически обрабатывается. Ожидающие запросы удаляются из очереди и выполняются повторно, а в случае неудачи они снова добавляются в очередь.
«но моя проблема в том, как определить, когда запросы находятся в ожидании слишком долго, и, например, определить время их ожидания и не выполнить их». - Это зависит от библиотеки/реализации, которую вы используете для выполнения своих запросов.
Чтобы решить эту проблему, я добавил проверку ожидающих и отклоненных запросов веб-сервиса в начале моей корневой саги:
function* handlePendingRequestsSaga() {
yield put({ type: actionClearPendingDataRequests.toString() });
yield put({ type: actionRetryRejectedDataRequests.toString() });
}
export default function* rootSaga() {
yield handlePendingRequestsSaga();
yield takeEvery(actionGetData.toString(), handleGetResource);
}
И в соответствующих редукторах тот, что для actionClearPendingDataRequests
, принимает запросы, которые были помечены как ожидающие, и перемещает их в число отклоненных, а тот, что для actionRetryRejectedDataRequests
, будет повторять запросы, которые ранее были помечены как отклоненные. Поскольку handlePendingRequestsSaga
срабатывает при инициализации (скажем, когда страница обновляется или впервые загружается), любые прерванные запросы будут помечены как отклоненные и автоматически повторены, а любые запросы, которые ранее не удались, также будут повторены (один раз). Если они снова терпят неудачу без перерыва, рабочий процесс страницы выполняется так, как предполагалось (показывает пользователю сообщение об ошибке для неудавшихся запросов и т. д.).
Для закрытого голосования: Это не вопрос, основанный на мнении. Ошибка, которую я пытаюсь устранить, заключается в том, что страница обновляется, когда ожидается запрос данных. Он застрянет в состоянии ожидания, и у него не будет возможности запустить другой запрос API.