Обрабатывайте проигнорированные или отмененные задачи с помощью takeLeading и takeLatest с помощью Redux Saga - PullRequest
0 голосов
/ 23 апреля 2020

Я создаю обобщенную 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 в каждом, но я очень хочу этого избежать. У меня есть подозрение, что это возможно с буферами, но у меня проблемы с оборачиванием их вокруг головы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...