Я создаю обобщенную c оболочку Saga в своей компании, чтобы позволить людям подключаться к конечной точке API с помощью самоуверенного и декларативного способа.
const TodoMethods = {
GetAll: new EndpointMethod<void, ITodoItem[]>('GET', TodoApi.getAllTodos, takeLeading),
GetById: new EndpointMethod<string, ITodoItem>('GET', TodoApi.getTodoById, takeEvery),
Add: new EndpointMethod<ITodoItem, ITodoItem>('POST', TodoApi.addTodo, takeEvery),
Delete: new EndpointMethod<ITodoItem, ITodoItem>('DELETE', TodoApi.deleteTodo, takeEvery),
Update: new EndpointMethod<ITodoItem, ITodoItem>('PATCH', TodoApi.updateTodo, takeEvery),
}
const TodoSlice = new EndpointSlice(
'Todo', // Name of the slice
'https://todo-backend-typescript.herokuapp.com/', // Endpoint Url
TodoMethods // List of methods available on the endpoint
)
Мы описываем набор методов (GET
, POST
, et c) и связанный EffectCreator
(takeEvery
, et c), которые описывают конечную точку, затем регистрируют эти методы в классе Endpoint
, который знает URL-адрес конечной точки API. Это создаст фрагмент состояния Redux и создаст все действия, создатели действий, редукторы и саги.
// Determine how to watch the execution scenario
function *rootSaga(): Generator {
// "effect" could be any EffectCreator, such as "takeEvery"
yield effect(actions.Execute, asyncSaga)
}
// Default implementation of the saga to handle the Execution action workflow
function *asyncSaga(action: AnyAction): Generator {
try {
yield put(actions.Executing(params, action.meta));
const response = yield call(apiFunction, action.payload);
yield put(actions.Success(response.data));
} catch (err) {
yield put(actions.Failure(err));
}
}
Каждый создатель действия свяжет уникальный запрос с запросом и передаст его обратно компоненту. поэтому наши компоненты могут искать состояние загрузки указанного c запроса. Это требует от нас отслеживания записи для каждого запроса в хранилище Redux, чтобы мы могли связать isFetching
/ isFetched
и другие метаданные с уникальным идентификатором.
Это прекрасно работает для takeEvery
, но когда 3 Компоненты запрашивают одну и ту же конечную точку одновременно при использовании takeLeading
, последующие задачи игнорируются. Это оставляет записи в моем хранилище Redux, которые все еще обозначены как isFetching
, и мои компоненты считают, что их данные все еще загружаются.
Как я могу отследить (а) какие задачи были фактически выполнены, (б) какие были игнорируется и (c) отправляет действие, чтобы сообщить моему компоненту, что запрос был заменен другим запросом?
Похоже, что единственный способ выполнить sh это может быть воссоздание EffectCreators и добавление мои собственные логики обработки c в каждом, но я очень хочу этого избежать. У меня есть подозрение, что это возможно с буферами, но у меня проблемы с оборачиванием их вокруг головы.