Запуск гонки между несколькими Effect-ами

Иногда мы запускаем несколько задач параллельно, но мы не хотим ждать их всех, нам просто нужно получить победителя: первый, который вернет результат (или исключение / Promise.reject).

Effect race запускает гонку между несколькими Effect-ами.

В следующем примере показан таск, который запускает запрос удаленной выборки и ограничивает ответ в течение 1 секунды.

import { race, take, put } from 'redux-saga/effects'
import { delay } from 'redux-saga'

function* fetchPostsWithTimeout() {
  const {posts, timeout} = yield race({
    posts: call(fetchApi, '/posts'),
    timeout: call(delay, 1000)
  })

  if (posts)
    put({type: 'POSTS_RECEIVED', posts})
  else
    put({type: 'TIMEOUT_ERROR'})
}

Еще одна полезная особенность race состоит в том, что она автоматически отменяет Effect-ы проигравших. Например, предположим, что у нас есть две кнопки:

  • Первый запускает задачу в фоновом режиме, которая выполняется в бесконечном цикле while (true) (например, синхронизация данных с сервером каждые x секунд).

  • После запуска фоновой задачи мы включаем вторую кнопку, которая отменяет задачу

import { race, take, put } from 'redux-saga/effects'

function* backgroundTask() {
  while (true) { ... }
}

function* watchStartBackgroundTask() {
  while (true) {
    yield take('START_BACKGROUND_TASK')
    yield race({
      task: call(backgroundTask),
      cancel: take('CANCEL_TASK')
    })
  }
}

В случае диспатча action CANCEL_TASK , Effect race автоматически отменяет backgroundTask, выбрасывая в нем исключение.

results matching ""

    No results matching ""