Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected behavior when emitting actions synchronously #765

Open
robmcm opened this issue Mar 16, 2022 · 1 comment
Open

Unexpected behavior when emitting actions synchronously #765

robmcm opened this issue Mar 16, 2022 · 1 comment

Comments

@robmcm
Copy link

robmcm commented Mar 16, 2022

Unexpected behavior when emitting actions synchronously

What is the current behavior?
When an epic dispatches an action synchronously, it will in turn synchronously call store.dispatch (https://github.com/redux-observable/redux-observable/blob/master/src/createEpicMiddleware.ts#L85). This means all reducers and epics will be called with the new action before the current action propagates through the remaining combined epics. This causes some confusion where the state$.value can differ from what would be expected (even inside the same state$ pipe).

If the current behavior is a bug, please provide the steps to reproduce and a minimal demo of the problem using JSBin, StackBlitz, or similar.

(action$, state$, dependencies) => {
    const initialState = state$.value; // Initial state
    return state$.pipe(
        tap(state => console.log(state === initialState), // Will return false
        startWith(actionToChangeState) // This action will be run through the reducers before state$ is subscribed to above
   )
}

What is the expected behavior?
I would expect the epics to dispatch actions after the current action/state has been passed to each epic in combine epics.
However I understand this has probably been around for a while, and may only crop up in more complex use cases (with multiple epics).
A workaround is to add delay(1) to the end of any epic that dispatches synchronously (specifically in response to an emit on state$ or action$).
If this is unlikely to be fixed it may be good to have it added to a "known issues" section in the docs?

Which versions of redux-observable, and which browser and OS are affected by this issue? Did this work in previous versions of redux-observable?
I think it has always been like this.

@robmcm
Copy link
Author

robmcm commented Mar 16, 2022

If epic1 dispatches action2 synchronously

Expected order:
reducer1(action1, state1),
reducer2(action1, state1),
epic1(action1, state1), // Dispatches action2, but waits for all epics to be called with current state/action
epic2(action1, state1),

reducer1(action2, state2),
reducer2(action2, state2),
epic1(action2, state2),
epic2(action2, state2)

Actual :
reducer1(action1, state1),
reducer2(action1, state1),
epic1(action1, state1), // Dispatches action2 and dispatch starts a new cycle
reducer1(action2, state2),
reducer2(action2, state2),
epic1(action2, state2),
epic2(action2, state2),
epic2(action1, state1),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant