Skip to content

Commit c816191

Browse files
committed
Merge pull request #131 from balloob/dont-allow-dispatch-while-dispatch
Raise error if trying to dispatch from observer
2 parents 2b31a26 + fad1ef9 commit c816191

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/reactor.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class Reactor {
5252
this.__batchDepth = 0
5353
// number of dispatches in the top most batch cycle
5454
this.__batchDispatchCount = 0
55+
56+
// keep track if we are currently dispatching
57+
this.__isDispatching = false
5558
}
5659

5760
/**
@@ -105,13 +108,22 @@ class Reactor {
105108
* @param {object|undefined} payload
106109
*/
107110
dispatch(actionType, payload) {
111+
if (this.__batchDepth === 0) {
112+
if (this.__isDispatching) {
113+
this.__isDispatching = false
114+
throw new Error('Dispatch may not be called while a dispatch is in progress')
115+
}
116+
this.__isDispatching = true
117+
}
118+
108119
var prevState = this.state
109120
this.state = this.__handleAction(prevState, actionType, payload)
110121

111122
if (this.__batchDepth > 0) {
112123
this.__batchDispatchCount++
113124
} else if (this.state !== prevState) {
114125
this.__notify()
126+
this.__isDispatching = false
115127
}
116128
}
117129

@@ -285,7 +297,10 @@ class Reactor {
285297

286298
if (this.__batchDepth <= 0) {
287299
if (this.__batchDispatchCount > 0) {
300+
// set to true to catch if dispatch called from observer
301+
this.__isDispatching = true
288302
this.__notify()
303+
this.__isDispatching = false
289304
}
290305
this.__batchDispatchCount = 0
291306
}

tests/reactor-tests.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,25 @@ describe('Reactor', () => {
179179

180180
expect(mockFn.calls.count()).toEqual(0)
181181
})
182+
183+
it('should raise an error if already dispatching another action', () => {
184+
reactor.observe([], state => reactor.dispatch('noop', {}))
185+
186+
expect(() => checkoutActions.setTaxPercent(5)).toThrow(
187+
new Error('Dispatch may not be called while a dispatch is in progress'))
188+
})
189+
190+
it('should keep working after it raised for dispatching while dispatching', () => {
191+
var unWatchFn = reactor.observe([], state => reactor.dispatch('noop', {}))
192+
193+
expect(() => checkoutActions.setTaxPercent(5)).toThrow(
194+
new Error('Dispatch may not be called while a dispatch is in progress'))
195+
196+
unWatchFn()
197+
198+
expect(() => checkoutActions.setTaxPercent(5)).not.toThrow(
199+
new Error('Dispatch may not be called while a dispatch is in progress'))
200+
})
182201
}) // when dispatching a relevant action
183202

184203
describe('#observe', () => {
@@ -1013,5 +1032,39 @@ describe('Reactor', () => {
10131032
expect(observeSpy.calls.count()).toBe(1)
10141033
expect(firstCallArg).toEqual(['one', 'two', 'three'])
10151034
})
1035+
1036+
it('should not allow dispatch to be called from an observer', () => {
1037+
reactor.observe([], state => reactor.dispatch('noop', {}))
1038+
1039+
expect(() => {
1040+
reactor.batch(() => {
1041+
reactor.dispatch('add', 'one')
1042+
reactor.dispatch('add', 'two')
1043+
})
1044+
}).toThrow(
1045+
new Error('Dispatch may not be called while a dispatch is in progress'))
1046+
})
1047+
1048+
it('should keep working after it raised for dispatching while dispatching', () => {
1049+
var unWatchFn = reactor.observe([], state => reactor.dispatch('noop', {}))
1050+
1051+
expect(() => {
1052+
reactor.batch(() => {
1053+
reactor.dispatch('add', 'one')
1054+
reactor.dispatch('add', 'two')
1055+
})
1056+
}).toThrow(
1057+
new Error('Dispatch may not be called while a dispatch is in progress'))
1058+
1059+
unWatchFn()
1060+
1061+
expect(() => {
1062+
reactor.batch(() => {
1063+
reactor.dispatch('add', 'one')
1064+
reactor.dispatch('add', 'two')
1065+
})
1066+
}).not.toThrow(
1067+
new Error('Dispatch may not be called while a dispatch is in progress'))
1068+
})
10161069
})
10171070
})

0 commit comments

Comments
 (0)