Implementing a Middleware for Async Actions in Redux 5.0.0

This example shows how to write a custom middleware in Redux 5.0.0 to handle asynchronous actions using the async/await syntax.
const asyncMiddleware = store => next => async action => {
  // If the 'action' is a function instead of an action object
  if (typeof action === 'function') {
    // Invoke the action function with 'dispatch' and 'getState' as arguments
    return action(store.dispatch, store.getState);

  // If the 'action' has a 'promise' property
  if (action.promise && typeof action.promise.then === 'function') {
    try {
      // Dispatch an action to indicate the start of an async operation
      store.dispatch({ type: `${action.type}_REQUEST` });
      // Wait for the promise to resolve and dispatch a success action with the result
      const response = await action.promise;
      return store.dispatch({ type: `${action.type}_SUCCESS`, payload: response });
    } catch (error) {
      // If the promise rejects, dispatch a failure action with the error
      return store.dispatch({ type: `${action.type}_FAILURE`, error });

  // For any other action, pass it down the middleware chain
  return next(action);
This middleware function intercepts actions before they reach the reducer. If the action is a function (thunk), it invokes the function with dispatch and getState. If the action has a promise property, the middleware handles the promise lifecycle, dispatching _REQUEST, _SUCCESS, and _FAILURE actions accordingly. For all other actions, it simply passes the action to the next middleware.