Skip to content

Commit b2ca72a

Browse files
committed
refactor batcher into singleton
1 parent 316bb09 commit b2ca72a

File tree

4 files changed

+69
-76
lines changed

4 files changed

+69
-76
lines changed

src/batcher.js

+47-71
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,52 @@
11
var _ = require('./util')
22

3+
// we have two separate queues: one for directive updates
4+
// and one for user watcher registered via $watch().
5+
// we want to guarantee directive updates to be called
6+
// before user watchers so that when user watchers are
7+
// triggered, the DOM would have already been in updated
8+
// state.
9+
var queue = []
10+
var userQueue = []
11+
var has = {}
12+
var waiting = false
13+
var flushing = false
14+
315
/**
4-
* The Batcher maintains a job queue to be run
5-
* async on the next event loop. A "job" can be any object
6-
* that implements the following interface:
7-
*
8-
* {
9-
* id: {Number} - optional
10-
* run: {Function}
11-
* user: {Boolean} - optional
12-
* }
13-
*
14-
* The `id` property is used to prevent duplication of jobs,
15-
* while jobs with `user:true` need to be processed after
16-
* all internal jobs have been processed first.
17-
*
18-
* In most cases a job will actually be a Watcher instance
19-
* which implements the above interface.
16+
* Reset the batcher's state.
2017
*/
2118

22-
function Batcher () {
23-
this.reset()
19+
function reset () {
20+
queue = []
21+
userQueue = []
22+
has = {}
23+
waiting = false
24+
flushing = false
2425
}
2526

26-
var p = Batcher.prototype
27+
/**
28+
* Flush both queues and run the jobs.
29+
*/
30+
31+
function flush () {
32+
flushing = true
33+
run(queue)
34+
run(userQueue)
35+
reset()
36+
}
2737

2838
/**
29-
* Reset the batcher's state.
39+
* Run the jobs in a single queue.
40+
*
41+
* @param {Array} queue
3042
*/
3143

32-
p.reset = function () {
33-
this.has = {}
34-
// we have two separate queues: one for directive updates
35-
// and one for user watcher registered via $watch().
36-
// we want to guarantee directive updates to be called
37-
// before user watchers so that when user watchers are
38-
// triggered, the DOM would have already been in updated
39-
// state.
40-
this.queue = []
41-
this.userQueue = []
42-
this.waiting = false
43-
this.flushing = false
44+
function run (queue) {
45+
// do not cache length because more jobs might be pushed
46+
// as we run existing jobs
47+
for (var i = 0; i < queue.length; i++) {
48+
queue[i].run()
49+
}
4450
}
4551

4652
/**
@@ -54,51 +60,21 @@ p.reset = function () {
5460
* - {Function} run
5561
*/
5662

57-
p.push = function (job) {
58-
if (!job.id || !this.has[job.id] || this.flushing) {
63+
exports.push = function (job) {
64+
if (!job.id || !has[job.id] || flushing) {
5965
// A user watcher callback could trigger another
6066
// directive update during the flushing; at that time
6167
// the directive queue would already have been run, so
6268
// we call that update immediately as it is pushed.
63-
if (this.flushing && !job.user) {
69+
if (flushing && !job.user) {
6470
job.run()
6571
return
6672
}
67-
var queue = job.user
68-
? this.userQueue
69-
: this.queue
70-
queue.push(job)
71-
this.has[job.id] = job
72-
if (!this.waiting) {
73-
this.waiting = true
74-
_.nextTick(this.flush, this)
73+
;(job.user ? userQueue : queue).push(job)
74+
has[job.id] = job
75+
if (!waiting) {
76+
waiting = true
77+
_.nextTick(flush)
7578
}
7679
}
77-
}
78-
79-
/**
80-
* Flush both queues and run the jobs.
81-
*/
82-
83-
p.flush = function () {
84-
this.flushing = true
85-
run(this.queue)
86-
run(this.userQueue)
87-
this.reset()
88-
}
89-
90-
/**
91-
* Run the jobs in a single queue.
92-
*
93-
* @param {Array} queue
94-
*/
95-
96-
function run (queue) {
97-
// do not cache length because more jobs might be pushed
98-
// as we run existing jobs
99-
for (var i = 0; i < queue.length; i++) {
100-
queue[i].run()
101-
}
102-
}
103-
104-
module.exports = Batcher
80+
}

src/watcher.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ var _ = require('./util')
22
var config = require('./config')
33
var Observer = require('./observer')
44
var expParser = require('./parsers/expression')
5-
var Batcher = require('./batcher')
6-
7-
var batcher = new Batcher()
5+
var batcher = require('./batcher')
86
var uid = 0
97

108
/**

test/unit/specs/batcher_spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
var Batcher = require('../../../src/batcher')
1+
var batcher = require('../../../src/batcher')
22
var nextTick = require('../../../src/util').nextTick
33

44
describe('Batcher', function () {
55

6-
var batcher = new Batcher()
76
var spy
87

98
beforeEach(function () {

test/unit/specs/util/env_spec.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var _ = require('../../../../src/util')
2+
3+
describe('Util - Environment', function () {
4+
5+
describe('nextTick', function () {
6+
7+
it('should accept context', function (done) {
8+
var ctx = {}
9+
_.nextTick(function () {
10+
this.id = 1
11+
}, ctx)
12+
_.nextTick(function () {
13+
expect(ctx.id).toBe(1)
14+
done()
15+
})
16+
})
17+
18+
})
19+
20+
})

0 commit comments

Comments
 (0)