Is it possible to await for dispatch is finish
Asked Answered
E

3

12

I have 2 actions, and I call from the first action to the second action .... and I need to wait until the second action is finished and only then continue with the action.

// first action
export const getDataFromAdmin = () => {
    return async (dispatch, getState) => {
        dispatch(getDeviceLocation());
        console.log('only after getDeviceLocation is finsih');
        AdminRepository.getDataFromAdminAndEnums(dispatch)
            .then(adminData => {
              //some code 
            })
            .catch(error => {
                console.log(`Splash Error = ${error.message}`);
            });
    };
};


//second action
export const getDeviceLocation = () => {
    return async dispatch => {
        dispatch({ type: actionsType.GET_DEVICE_LOCATION });
        LocationManager.getCurrentPosition()
            .then(location => {
         
                dispatch({ type: actionsType.GET_DEVICE_LOCATION_SUCCESS });
            })
            .catch(error => {
                dispatch({ type: actionsType.GET_DEVICE_LOCATION_ERROR, message: error.message });
            });
    };
};
Ensoul answered 1/9, 2020 at 11:37 Comment(1)
Dispatch calls are sync BUT they can trigger async calls, which - when they finish - dispatch other actions (see: redux.js.org/advanced/async-actions#async-action-creators)Macmacabre
H
4

Yes you can await dispatch, but only if you are using redux-thunk middleware.

dispatch is a synchronous action by default. redux-thunk middleware allows you to dispatch actions which are a function of dispatch, like the actions in your question, in addition to the standard { type: 'SOME_NAME' } action objects. redux-thunk also makes it so that dispatching these "thunk" actions is asyncronous. This allows you to use aysnc/await or Promise.then() when you call dispatch(myThunkAction());

async function someFunction() {
    await dispatch(myThunkAction());
    doSomethingElse();
}
dispatch(myThunkAction()).then(() => {
    doSomethingElse();
});

Here is an example from the redux-thunk documentation:

// In fact I can write action creators that dispatch
// actions and async actions from other action creators,
// and I can build my control flow with Promises.

function makeSandwichesForEverybody() {
  return function (dispatch, getState) {
    if (!getState().sandwiches.isShopOpen) {
      // You don’t have to return Promises, but it’s a handy convention
      // so the caller can always call .then() on async dispatch result.

      return Promise.resolve()
    }

    // We can dispatch both plain object actions and other thunks,
    // which lets us compose the asynchronous actions in a single flow.

    return dispatch(makeASandwichWithSecretSauce('My Grandma'))
      .then(() =>
        Promise.all([
          dispatch(makeASandwichWithSecretSauce('Me')),
          dispatch(makeASandwichWithSecretSauce('My wife'))
        ])
      )
      .then(() => dispatch(makeASandwichWithSecretSauce('Our kids')))
      .then(() =>
        dispatch(
          getState().myMoney > 42
            ? withdrawMoney(42)
            : apologize('Me', 'The Sandwich Shop')
        )
      )
  }
}

You can view the complete code in the redux-thunk docs section on Composition to see how they define the makeASandwichWithSecretSauce thunk.


The resolved value of the Promise will be whatever you return in your myThunkAction function. Typically thunks will call dispatch and will not return anything, so this feature is rarely used.

Any return value from the inner function will be available as the return value of dispatch itself. This is convenient for orchestrating an asynchronous control flow with thunk action creators dispatching each other and returning Promises to wait for each other’s completion. (source)

async function someFunction() {
    const result = await dispatch(myThunkAction());
    doSomethingWithResult(result);
}
dispatch(myThunkAction()).then((result) => {
    doSomethingWithResult(result);
});
Homonym answered 15/2, 2023 at 19:0 Comment(1)
Thanks a lot for the details, that solves the case for me.But
L
2

No, it's not possible because dispatching an action is something like triggering action and action just invoke either middleware or reducer that's it. The action doesn't wait to complete the reducer or middleware. It just invokes and finishes his job.

Laxity answered 1/9, 2020 at 11:43 Comment(0)
E
1

Ok, so in the end I make async await by pass dispatch as a parmeter to the function.

Ensoul answered 2/9, 2020 at 12:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.