简体   繁体   中英

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM