-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Why saga.run() is out of order in the Redux middleware stack? #1651
Comments
The main rationale here is to ensure that We had to decide on some logic there and this seems better for most cases, so unfortunately you'll have to work around it. |
I think the main reason of disorder is the scheduler. function sagaMiddleware({ getState, dispatch }) {
// ... other code
return next => action => {
// ... other code...
const result = next(action) // hit reducers
channel.put(action) // LINE-A
return result
} Note that at LINE-A, the Sorry for using the implementation detail to explain this strange behavior, hope this could be understood by you guys. |
Thanks for the explanation. Good to know. |
saga.run() is out of order in the Redux middleware stack
https://codesandbox.io/s/lp7on8mjpz
When dispatching an action, the order of the middleware (including saga) in the Redux is not in the original order. For example, I have 2 middleware, and between them, I have a saga middleware. The 2 middleware will always run first, before the saga.
My store enhancer looks like this:
And my saga looks like this:
I always see:
I understand why 2A/2B happen that way. But I am not quite sure the primary reason we want to run 2C after 3.
Investigating into
redux-saga
code, I found that inmiddleware.js:44
, it specifically delayed the run of the saga middleware. It only run after all middleware has completed the job, i.e.next()
is not called before processing of the default channel.I tried to look into documentations but couldn't find a place that mention this. I think this is by design, but I would like to know why it is designed this way.
Because of this design, it is very difficult to mix-and-match middleware and saga. If there is an action that need to be handled by saga before the middleware, it will be impossible without splitting it into 2 actions. That also means, if I need to migrate my app from middleware to saga progressively, there will be a chance that my app will be broken until I move everything to saga.
For example, my app have a logic to send only after connect. (The code is simplified for readability, may not compile.)
Then in my app side of the code, I have a middleware that do "send-on-connect":
The "send-on-connect" code will not work because
sendLoop
did not receiveCONNECTED
yet, so it lost theSEND
action. To workaround, either:PREPARE_CONNECTED
, prime thesendLoop
on this actionI understand this could be by design, but I would like to understand the rationale behind.
Thanks.
The text was updated successfully, but these errors were encountered: