Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux middleware async function

I have a redux middleware that interacts with a rest api. I recently started rewriting some fetch functions using async/await.

For this to make the most sense for me, I would need the middleware function itself to be an async function so that I can use "await" and try/catch blocks on those other async functions I have created as opposed to having to use .then, .catch.

So far I have this:

const apiMiddleware = ({
  dispatch,
  getState
}) => next => async action => {
  switch (action.type) {
   //...
   }
  next(action);
};

Please note the use of async keyword before "action". So far this seems to be working as expected, I am able to await other async functions from that middleware. However, since I was not able to find documentation on this, I was wondering if what I did truly is valid.

Thank you

like image 233
roboris Avatar asked Oct 08 '17 17:10

roboris


People also ask

Can Redux async middleware?

Redux middleware were designed to enable writing logic that has side effects. As we said in Part 4, a Redux middleware can do anything when it sees a dispatched action: log something, modify the action, delay the action, make an async call, and more.

Why do we need to use Redux middleware to perform asynchronous activity?

Redux Middleware allows you to intercept every action sent to the reducer so you can make changes to the action or cancel the action. Middleware helps you with logging, error reporting, making asynchronous requests, and a whole lot more.

Is Redux dispatch asynchronous?

However, the flow of Redux's state management tasks is completely synchronous: dispatching an action immediately generates the chain of calls to middleware and reducers to carry out the state transition.

What are typical middleware choices for handling asynchronous calls in Redux?

There are two very popular middleware libraries that allow for side effects and asynchronous actions: Redux Thunk and Redux Saga. In this post, you will explore Redux Thunk. Thunk is a programming concept where a function is used to delay the evaluation/calculation of an operation.


1 Answers

Have you considered looking into Redux Sagas? https://redux-saga.js.org/

This is specifically created for making working with async functions more manageable. And i would think that implementing this, can make your async functions more understandable, and easier to debug.

Your code is valid javascript, but you might experience inconsistency in the state, because of the async nature of your functions.

If your async action isn't finished before your next action is dispatched, the second action will use a version of the state, that might be mutated by the first action, while running.

This behavior can give you issues like you described.


Edit: After i learned you are already using redux-thunks

In redux thunks, you can chain actions dispatches, with await, and leveraging the return of a dispatch.

An example on how to chain actions with redux-thunks from this article: https://blog.jscrambler.com/async-dispatch-chaining-with-redux-thunk/

const dispatchChaining = () => async (dispatch) => {
  await Promise.all([
    dispatch(loadPosts()), // <-- async dispatch chaining in action
    dispatch(loadProfile())
  ]);

  return dispatch(updateDone());
};

const actions = redux.bindActionCreators({dispatchChaining}, store.dispatch);
actions.dispatchChaining().then(() => unsubscribe());

Note that as long as there is a return these dispatches are thenable. The bonus here is we can fire async dispatches in parallel and wait for both to finish. Then, update isDone knowing both calls are done without any unpredictable behavior. These reusable thunks can live in different parts of the store to maintain separation of concerns.

like image 75
Bjørn Nyborg Avatar answered Oct 01 '22 07:10

Bjørn Nyborg