Blog>
Snippets

createAsyncThunk with Cancellation and Timeouts

Provide a createAsyncThunk example that includes an abort signal and a timeout to cancel recursive API requests after a certain period of time or under certain conditions.
import { createAsyncThunk } from '@reduxjs/toolkit';
import { fetchWithTimeout } from './fetchWithTimeout'; // Assume this is a fetch wrapper with timeout

// Action Type
const POLL_DATA = 'data/pollStatus';

// Async Thunk for Polling
export const pollData = createAsyncThunk(
  POLL_DATA,
  async (jobId, { signal, rejectWithValue }) => {
    try {
      // Perform the API request with a timeout and abort signal
      const response = await fetchWithTimeout(`/api/jobs/${jobId}`, { signal });
      if (!response.ok) {
        throw new Error('Server error');
      }
      return await response.json();
    } catch (error) {
      if (error.name === 'AbortError') {
        // Handle abort as a specific case, if needed
        return rejectWithValue('Polling was cancelled.');
      } else {
        // Handle other errors
        return rejectWithValue(error.message);
      }
    }
  },
  {
    condition: (jobId, { getState }) => {
      // Optionally cancel the request from being made if a condition is met
      const { polling } = getState();
      if (polling.shouldStop) {
        // Return false to cancel the execution
        return false;
      }
    }
  }
);
This code snippet defines an async thunk 'pollData' using createAsyncThunk for polling an API endpoint with cancellation and timeouts. It includes an 'AbortController' signal and a conditional check to cancel the requests. The 'fetchWithTimeout' function is a hypothetical fetch call with integrated timeout logic.