Redux Async Queue Middleware
raw JSON →redux-async-queue is a Redux middleware designed to manage the sequential execution of asynchronous actions. It allows developers to define multiple distinct queues, ensuring that actions belonging to a specific queue are processed one at a time, in the order they were dispatched. Each queued action dispatches a `callback` that receives `next`, `dispatch`, and `getState`, requiring an explicit call to `next()` to signal completion and allow the next item in the queue to proceed. This pattern is useful for operations that must be serialized, like sequential API calls or resource-intensive tasks that cannot run concurrently. The package is currently at version 1.0.0, suggesting a stable, though possibly no longer actively developed, state. Its differentiator lies in its explicit queue naming and manual progression mechanism, contrasting with more general-purpose async Redux patterns like thunks or sagas which handle concurrency differently or rely on more advanced paradigms. The library focuses solely on ordered async execution within a Redux store.
Common errors
error TypeError: ReduxAsyncQueue is not a function ↓
const ReduxAsyncQueue = require('redux-async-queue'); to const ReduxAsyncQueue = require('redux-async-queue').default; error My Redux async actions are not executing in order or are getting stuck after the first one. ↓
next() is called after your asynchronous operation completes within the callback: callback: (next, dispatch, getState) => { asyncOperation().then(() => { dispatch(someAction()); next(); }); } Warnings
gotcha When importing the middleware using CommonJS `require`, developers must access the `.default` property. Failing to do so will result in `TypeError: ReduxAsyncQueue is not a function` because the module's top-level export is the ES module wrapper, not the function itself. ↓
gotcha The `callback` function provided in a queued action *must* explicitly call `next()` to signal completion of the current asynchronous task. If `next()` is not called, the queue will halt indefinitely, and subsequent actions in that queue will never execute. ↓
gotcha The library's approach to async action management is somewhat foundational. With the evolution of Redux and the rise of Redux Toolkit, which integrates `redux-thunk` by default and has strong support for `redux-saga` or `redux-observable`, this middleware might not be the most idiomatic or integrated choice for new projects, especially those using Redux Toolkit. It represents an older pattern for managing sequential async operations. ↓
deprecated The package appears to be in maintenance mode or abandoned, with version 1.0.0 being the only or final major release documented. This suggests a lack of active development, potential compatibility issues with very recent Redux versions or TypeScript evolutions, and no new features or bug fixes. Security updates are unlikely. ↓
Install
npm install redux-async-queue yarn add redux-async-queue pnpm add redux-async-queue Imports
- ReduxAsyncQueue wrong
import { ReduxAsyncQueue } from 'redux-async-queue';correctimport ReduxAsyncQueue from 'redux-async-queue'; - ReduxAsyncQueue (CommonJS) wrong
const ReduxAsyncQueue = require('redux-async-queue');correctconst ReduxAsyncQueue = require('redux-async-queue').default; - Queue Action Structure
const action = { queue: 'MY_QUEUE', callback: (next, dispatch, getState) => { /* ... */ next(); } };
Quickstart
import { createStore, applyMiddleware } from 'redux';
import ReduxAsyncQueue from 'redux-async-queue';
// Basic Redux reducer (e.g., in reducers/index.js)
const initialState = { burgersMade: 0, burgerQueue: [] };
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'MAKE_BURGER_COMPLETE':
console.log(`Burger made: ${action.payload}`);
return { ...state, burgersMade: state.burgersMade + 1, burgerQueue: [...state.burgerQueue, action.payload] };
default:
return state;
}
};
// Create the Redux store with the async queue middleware
const store = createStore(
reducer,
applyMiddleware(ReduxAsyncQueue)
);
// Example function to simulate async ingredient fetching (e.g., an API call)
function getIngredients(style) {
console.log(`Getting ingredients for ${style} burger...`);
return new Promise(resolve => {
setTimeout(() => {
console.log(`Ingredients ready for ${style} burger.`);
resolve(`${style} burger`);
}, Math.random() * 1500 + 500); // Simulate network delay
});
}
// Action creator for the actual burger making
function makeBurgerComplete(burgerType) {
return {
type: 'MAKE_BURGER_COMPLETE',
payload: burgerType,
};
}
// Action creator to add a burger to the queue
function queueMakeBurger(style) {
return {
queue: 'BURGER_QUEUE', // Name of the queue
callback: (next, dispatch, getState) => {
console.log(`Starting to make a ${style} burger.`);
getIngredients(style).then(burger => {
dispatch(makeBurgerComplete(burger)); // Dispatch a regular Redux action
next(); // IMPORTANT: Signal that this item in the queue is complete
});
}
};
}
// Dispatch multiple actions to the queue
console.log('Dispatching burger requests...');
store.dispatch(queueMakeBurger('Cheeseburger'));
store.dispatch(queueMakeBurger('Bacon Burger'));
store.dispatch(queueMakeBurger('Veggie Burger'));
// Output current state after initial dispatches
console.log('Current state:', store.getState());
// Example: Monitor store for changes
store.subscribe(() => {
console.log('Store updated:', store.getState().burgersMade, 'burgers made.');
});