Blog>
Snippets

Implementing a race Condition in Redux Saga

Illustrate using the `race` effect to handle competing tasks in sagas, where only the first task to finish gets handled.
import { race, take, call, put } from 'redux-saga/effects';

function* watchStartTasks() {
  while (true) {
    // Wait for the 'START_TASKS' action to be dispatched
    yield take('START_TASKS');
    yield race({
      task1: call(handleTask1),
      task2: call(handleTask2)
    });
  }
}
This code sets up a watcher saga that waits for a 'START_TASKS' action. Upon receiving this action, it triggers `race` with two tasks: `handleTask1` and `handleTask2`. Only the first task to complete will have its result handled, effectively cancelling the slower task.
function* handleTask1() {
  try {
    const data = yield call(fetchDataFromApi1);
    yield put({ type: 'TASK1_SUCCESS', data });
  } catch (error) {
    yield put({ type: 'TASK_FAILURE', error });
  }
}

function* handleTask2() {
  try {
    const data = yield call(fetchDataFromApi2);
    yield put({ type: 'TASK2_SUCCESS', data });
  } catch (error) {
    yield put({ type: 'TASK_FAILURE', error });
  }
}
These are the worker sagas for `handleTask1` and `handleTask2`. Each attempts to fetch data from a different API. On success, they dispatch a success action specific to the task. On failure, they dispatch a generic task failure action.