File tree Expand file tree Collapse file tree 2 files changed +23
-13
lines changed Expand file tree Collapse file tree 2 files changed +23
-13
lines changed Original file line number Diff line number Diff line change @@ -4,36 +4,46 @@ import { getBatch } from './batch'
44// well as nesting subscriptions of descendant components, so that we can ensure the
55// ancestor components re-render before descendants
66
7+ const CLEARED = null
78const nullListeners = { notify ( ) { } }
89
910function createListenerCollection ( ) {
1011 const batch = getBatch ( )
11- let listeners = { }
12- let id = 0
12+ // the current/next pattern is copied from redux's createStore code.
13+ // TODO: refactor+expose that code to be reusable here?
14+ let current = [ ]
15+ let next = [ ]
1316
1417 return {
1518 clear ( ) {
16- listeners = { }
19+ next = CLEARED
20+ current = CLEARED
1721 } ,
1822
1923 notify ( ) {
24+ const listeners = ( current = next )
2025 batch ( ( ) => {
21- for ( const id in listeners ) {
22- listeners [ id ] ( )
26+ for ( let i = 0 ; i < listeners . length ; i ++ ) {
27+ listeners [ i ] ( )
2328 }
2429 } )
2530 } ,
2631
2732 get ( ) {
28- return listeners
33+ return next
2934 } ,
3035
3136 subscribe ( listener ) {
32- const currentId = id ++
33- listeners [ currentId ] = listener
37+ let isSubscribed = true
38+ if ( next === current ) next = current . slice ( )
39+ next . push ( listener )
3440
3541 return function unsubscribe ( ) {
36- delete listeners [ currentId ]
42+ if ( ! isSubscribed || current === CLEARED ) return
43+ isSubscribed = false
44+
45+ if ( next === current ) next = current . slice ( )
46+ next . splice ( next . indexOf ( listener ) , 1 )
3747 }
3848 }
3949 }
Original file line number Diff line number Diff line change @@ -97,11 +97,11 @@ describe('React', () => {
9797 </ ProviderMock >
9898 )
9999
100- expect ( Object . keys ( rootSubscription . listeners . get ( ) ) . length ) . toBe ( 1 )
100+ expect ( rootSubscription . listeners . get ( ) . length ) . toBe ( 1 )
101101
102102 store . dispatch ( { type : '' } )
103103
104- expect ( Object . keys ( rootSubscription . listeners . get ( ) ) . length ) . toBe ( 2 )
104+ expect ( rootSubscription . listeners . get ( ) . length ) . toBe ( 2 )
105105 } )
106106
107107 it ( 'unsubscribes when the component is unmounted' , ( ) => {
@@ -125,11 +125,11 @@ describe('React', () => {
125125 </ ProviderMock >
126126 )
127127
128- expect ( Object . keys ( rootSubscription . listeners . get ( ) ) . length ) . toBe ( 2 )
128+ expect ( rootSubscription . listeners . get ( ) . length ) . toBe ( 2 )
129129
130130 store . dispatch ( { type : '' } )
131131
132- expect ( Object . keys ( rootSubscription . listeners . get ( ) ) . length ) . toBe ( 1 )
132+ expect ( rootSubscription . listeners . get ( ) . length ) . toBe ( 1 )
133133 } )
134134
135135 it ( 'notices store updates between render and store subscription effect' , ( ) => {
You can’t perform that action at this time.
0 commit comments