Skip to content

Commit 483c387

Browse files
committed
avoid useless calls to listeners
1 parent cb5a00b commit 483c387

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

src/createStore.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,9 @@ export default function createStore(reducer, preloadedState, enhancer) {
5757
var currentReducer = reducer
5858
var currentState = preloadedState
5959
var currentListeners = []
60-
var nextListeners = currentListeners
60+
var listeners = []
6161
var isDispatching = false
6262

63-
function ensureCanMutateNextListeners() {
64-
if (nextListeners === currentListeners) {
65-
nextListeners = currentListeners.slice()
66-
}
67-
}
68-
6963
/**
7064
* Reads the state tree managed by the store.
7165
*
@@ -122,8 +116,7 @@ export default function createStore(reducer, preloadedState, enhancer) {
122116

123117
var isSubscribed = true
124118

125-
ensureCanMutateNextListeners()
126-
nextListeners.push(listener)
119+
currentListeners.push(listener)
127120

128121
return function unsubscribe() {
129122
if (!isSubscribed) {
@@ -139,9 +132,14 @@ export default function createStore(reducer, preloadedState, enhancer) {
139132

140133
isSubscribed = false
141134

142-
ensureCanMutateNextListeners()
143-
var index = nextListeners.indexOf(listener)
144-
nextListeners.splice(index, 1)
135+
let index = listeners.indexOf(listener)
136+
if (index !== -1) {
137+
listener()
138+
listeners.splice(index, 1)
139+
}
140+
141+
index = currentListeners.indexOf(listener)
142+
currentListeners.splice(index, 1)
145143
}
146144
}
147145

@@ -196,9 +194,9 @@ export default function createStore(reducer, preloadedState, enhancer) {
196194
isDispatching = false
197195
}
198196

199-
var listeners = currentListeners = nextListeners
200-
for (var i = 0; i < listeners.length; i++) {
201-
listeners[i]()
197+
listeners = currentListeners.slice()
198+
while (listeners.length) {
199+
listeners.shift()()
202200
}
203201

204202
return action

test/createStore.spec.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import expect from 'expect'
22
import { createStore, combineReducers } from '../src/index'
3-
import {
4-
addTodo,
5-
dispatchInMiddle,
3+
import {
4+
addTodo,
5+
dispatchInMiddle,
66
getStateInMiddle,
77
subscribeInMiddle,
88
unsubscribeInMiddle,
9-
throwError,
10-
unknownAction
9+
throwError,
10+
unknownAction
1111
} from './helpers/actionCreators'
1212
import * as reducers from './helpers/reducers'
1313
import * as Rx from 'rxjs'
@@ -388,18 +388,40 @@ describe('createStore', () => {
388388

389389
store.dispatch(unknownAction())
390390
expect(listener1.calls.length).toBe(1)
391-
expect(listener2.calls.length).toBe(2)
392-
expect(listener3.calls.length).toBe(2)
391+
expect(listener2.calls.length).toBe(1)
392+
expect(listener3.calls.length).toBe(1)
393393
expect(listener4.calls.length).toBe(1)
394394

395395
unsubscribe4()
396396
store.dispatch(unknownAction())
397397
expect(listener1.calls.length).toBe(1)
398-
expect(listener2.calls.length).toBe(3)
399-
expect(listener3.calls.length).toBe(3)
398+
expect(listener2.calls.length).toBe(2)
399+
expect(listener3.calls.length).toBe(2)
400400
expect(listener4.calls.length).toBe(1)
401401
})
402402

403+
it('notifies a listener unsubscribed with nested dispatch with the new state', () => {
404+
const store = createStore(reducers.todos)
405+
406+
var firstCall = true
407+
const listener1 = expect.createSpy().andCall(() => {
408+
unsubscribe2()
409+
if (firstCall) {
410+
firstCall = false
411+
store.dispatch(unknownAction())
412+
}
413+
})
414+
const listener2 = expect.createSpy()
415+
416+
store.subscribe(listener1)
417+
let unsubscribe2 = store.subscribe(listener2)
418+
419+
store.dispatch(unknownAction())
420+
expect(listener1.calls.length).toBe(2)
421+
expect(listener2.calls.length).toBe(1)
422+
})
423+
424+
403425
it('provides an up-to-date state when a subscriber is notified', done => {
404426
const store = createStore(reducers.todos)
405427
store.subscribe(() => {

0 commit comments

Comments
 (0)