how to understand function ensureCanMutateNextListeners? https://github.com/reactjs/redux/blob/master/src/createStore.js
相关问题
- How to toggle on Order in ReactJS
- Refreshing page gives Cannot GET /page_url in reac
- Adding a timeout to a render function in ReactJS
- React Native Inline style for multiple Text in sin
- Issue with React.PropTypes.func.isRequired
相关文章
- Cannot find module 'redux' 怎么解决?
- Why would we use useEffect without a dependency ar
- Is it possible to get ref of props.children?
- Stateless function components cannot be given refs
- React testing library: Test attribute / prop
- React/JestJS/Enzyme: How to test for ref function?
- Material-UI [v0.x] RaisedButton on hover styles
- Remove expo from react native
This question has been troubling me for quite some while, while the answer and blog post above offers the core idea, it doesn't give a concrete example.
My thinking process was: javaScript is single threaded, any function has run to completion behavior - so it doesn't really make sense to say
subscribe
has to worry whether there's a current dispatch operation going on. If we are inside functionsubscribe
, it's literally impossible to be also insidedispatch
: as nowhere inside the body ofsubscribe
isdispatch
being called, directly or indirectly.With that said I just realized a flaw in the above logic today, and thought I'd share here. The explanation is while inside
subscribe
,dispatch
will not be running, but the reverse is not true.subscribe
(andunsubscribe
) could be running insidedispatch
. Here's source ofdispatch
:Looks innocent enough right? Notice the short line:
listener()
.listener
is supplied by user ofredux
, and literally can be any function - includingsubscribe
(or a function callsstore.subscribe
). Finally, Here's an actual example:Now what happens when we dispatch? Suppose
ensureCanMutateNextListeners
is not used, andsubscribe
actually push listener tocurrentListeners
mutablly.Will loop through all listeners:
Initially there's only one listener:
listeners === [doSubscribe]
, so we calllistener[0
], a.k.adoSubscribe
, which callsstore.subscribe
and will push functiondoSubscribe
tolisteners
, nowlisteners
have two items! So the loop will call the second functionlisteners[1]
, which adds anotherlistener
, now we have three items... BecausedoSubscribe
subscribes itself, the loop will keeps on going, and run forever! Of course, a fix to prevent this particular infinite loop can be:But there can be other situations that mutates listeners array in unexpected way by some
listener
even if using onlyredux
public api.Therefore,
ensureCanMutateNextListeners
is introduced as a general solution. Inside dispatch, any indirect call tosubscribe
andunsubscribe
(only two public functionsredux
allows you to modify listeners) will mutate a copy ofcurrentListeners
- producing more predictable behaviors. In the example above, with the use ofensureCanMutateNextListeners
,doSubscribe
will add a add itself to a copy oflisteners
when called, the loop indispatch
remain unaffected and complete without any issues.It's a good question. Call @gaearon here
Posting relevant sections obtained from Aaron Powell's blog post here
Sample implementation of
subscribe
function fromredux
For every
dispatch
performed, we must notify everysubscriber
.From the blog
Continued ...