Reputation: 2465
I am in the process of trying to setup redux, react-redux and redux-thunk. Thinks are generally going well but I have a question about how things are supposed to look when chaining multiple async actions together.
Specifically I have a scenario where the actions can be invoked individually or indirectly by another action which can invoke them. My question is how should selectItem
be authored if I want to be idiomatic?
action.js
export function fetchByContext(contextId) {
return dispatch => {
_fetchByContext(messages => {
dispatch({ type: RECEIVE_MESSAGES, ... });
});
};
};
export function subscribeByContext(contextId) {
return dispatch => {
_subscribeByContext(messages => {
dispatch({ type: RECEIVE_MESSAGES, ... });
});
};
};
export function selectItem(contextId) {
return dispatch => {
subscribeByContext(contextId)(dispatch);
fetchByContext(contextId)(dispatch);
};
};
Upvotes: 1
Views: 1994
Reputation: 40296
I believe the key is that (ref):
Any return value from the inner function will be available as the return value of dispatch itself
If the inner functions of fetchByContext()
, subscribeByContext()
return a promise, these could be chained in series or run in parallel from selectItem()
. An untested implementation, assuming neither _fetchByContext()
nor _subscribeByContext()
return a promise would be:
export function fetchByContext(contextId) {
return dispatch => {
return new Promise((resolve, reject) => {
_fetchByContext(messages => {
dispatch({ type: RECEIVE_MESSAGES, ... });
resolve(messages);
});
});
};
};
export function subscribeByContext(contextId) {
return dispatch => {
return new Promise((resolve, reject) => {
_subscribeByContext(messages => {
dispatch({ type: RECEIVE_MESSAGES, ... });
resolve(messages);
});
});
};
};
export function selectItem(contextId) {
return dispatch => {
// CALL IN SERIES
return dispatch(subscribeByContext(contextId))
.then(() => dispatch(fetchByContext(contextId)));
// CALL IN PARALLEL (alternative to the code above; this is probably not what you want - just keeping for reference)
return Promise.all(
dispatch(subscribeByContext(contextId)),
dispatch(fetchByContext(contextId))
);
};
}
Again please note the code above is untested, just in hope of giving an idea for the general solution.
Upvotes: 1