Skip to content

Commit 9013fbb

Browse files
committed
warn against infinite update loops
1 parent 0894903 commit 9013fbb

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

src/batcher.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var _ = require('./util')
2+
var MAX_UPDATE_COUNT = 10
23

34
// we have two separate queues: one for directive updates
45
// and one for user watcher registered via $watch().
@@ -61,7 +62,21 @@ function run (queue) {
6162
*/
6263

6364
exports.push = function (job) {
64-
if (!job.id || !has[job.id] || flushing) {
65+
var id = job.id
66+
if (!id || !has[id] || flushing) {
67+
if (!has[id]) {
68+
has[id] = 1
69+
} else {
70+
has[id]++
71+
// detect possible infinite update loops
72+
if (has[id] > MAX_UPDATE_COUNT) {
73+
_.warn(
74+
'You may have an infinite update loop for the ' +
75+
'watcher with expression: "' + job.expression + '".'
76+
)
77+
return
78+
}
79+
}
6580
// A user watcher callback could trigger another
6681
// directive update during the flushing; at that time
6782
// the directive queue would already have been run, so
@@ -71,7 +86,6 @@ exports.push = function (job) {
7186
return
7287
}
7388
;(job.user ? userQueue : queue).push(job)
74-
has[job.id] = job
7589
if (!waiting) {
7690
waiting = true
7791
_.nextTick(flush)

test/unit/specs/batcher_spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
var _ = require('../../../src/util')
12
var batcher = require('../../../src/batcher')
23
var nextTick = require('../../../src/util').nextTick
34

@@ -7,6 +8,7 @@ describe('Batcher', function () {
78

89
beforeEach(function () {
910
spy = jasmine.createSpy('batcher')
11+
spyOn(_, 'warn')
1012
})
1113

1214
it('push', function (done) {
@@ -80,4 +82,21 @@ describe('Batcher', function () {
8082
})
8183
})
8284

85+
it('warn against infinite update loops', function (done) {
86+
var count = 0
87+
var job = {
88+
id: 1,
89+
run: function () {
90+
count++
91+
batcher.push(job)
92+
}
93+
}
94+
batcher.push(job)
95+
nextTick(function () {
96+
expect(count).not.toBe(0)
97+
expect(_.warn).toHaveBeenCalled()
98+
done()
99+
})
100+
})
101+
83102
})

0 commit comments

Comments
 (0)