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

Simplify createStore(), remove nextListeners & ensureCanMutateNextListeners() #2376

Conversation

robertpenner
Copy link

  • If we treat currentListeners as a read-only array, createStore()'s implementation can be simplified.
  • nextListeners and ensureCanMutateNextListeners() are unnecessary when we assign new arrays to currentListeners but never mutate it.
  • The code is easier to follow when we don't have to keep track of current vs. next listeners.
  • dispatch() remains free of the cost of creating new arrays.

@markerikson
Copy link
Contributor

I'm not clear on the exact history of why the current listeners logic is the way it is, but I'm pretty sure it has to do with the subtleties regarding more dispatches happening in subscription callbacks, and things like that.

My default response to PRs like this that mostly make changes for the sake of style is "No, unless it really is fixing an actual bug". I wouldn't want to consider merging something like this until I fully understand exactly why the current code is written that way.

I would request that you look back through the history of createStore and review why the current code structure exists, then recap the reasons in this thread. If this change violates any of the existing assumptions about behavior and timing, then it's not an option.

@timdorr
Copy link
Member

timdorr commented May 3, 2017

This would be a breaking change. We have very specific behaviors for how subscriptions are handled, particularly if you dispatch or subscribe/unsubscribe from within a listener.

I'd rather do this via an external library, so we can avoid dealing with the subtleties ourselves. Check out #1729 for an example.

@timdorr timdorr closed this May 3, 2017
@robertpenner
Copy link
Author

@timdorr How do you know this is a breaking change when it passes all the unit tests?

@robertpenner
Copy link
Author

@markerikson Thanks for the feedback. I read the history of createStore() carefully before making this change, and I confirmed that this new code satisfies the following required behaviors of Redux:

  • supports multiple subscriptions
  • only removes listener once when unsubscribe is called
  • only removes relevant listener when unsubscribe is called
  • supports removing a subscription within a subscription
  • delays unsubscribe until the end of current dispatch
  • delays subscribe until the end of current dispatch
  • uses the last snapshot of subscribers during nested dispatch
  • provides an up-to-date state when a subscriber is notified
  • does not leak private listeners array
  • only accepts plain object actions
  • handles nested dispatches gracefully
  • does not allow dispatch() from within a reducer
  • recovers from an error within a reducer
  • throws if listener is not a function
  • should be subscribable
  • should throw a TypeError if an observer object is not supplied to subscribe
  • should return a subscription object when subscribed
  • should pass an integration test with no unsubscribe
  • should pass an integration test with an unsubscribe
  • should pass an integration test with a common library (RxJS)

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

Successfully merging this pull request may close these issues.

3 participants