|
|
@@ -1,46 +1,52 @@
|
|
|
var _ = require('./util')
|
|
|
|
|
|
+// we have two separate queues: one for directive updates
|
|
|
+// and one for user watcher registered via $watch().
|
|
|
+// we want to guarantee directive updates to be called
|
|
|
+// before user watchers so that when user watchers are
|
|
|
+// triggered, the DOM would have already been in updated
|
|
|
+// state.
|
|
|
+var queue = []
|
|
|
+var userQueue = []
|
|
|
+var has = {}
|
|
|
+var waiting = false
|
|
|
+var flushing = false
|
|
|
+
|
|
|
/**
|
|
|
- * The Batcher maintains a job queue to be run
|
|
|
- * async on the next event loop. A "job" can be any object
|
|
|
- * that implements the following interface:
|
|
|
- *
|
|
|
- * {
|
|
|
- * id: {Number} - optional
|
|
|
- * run: {Function}
|
|
|
- * user: {Boolean} - optional
|
|
|
- * }
|
|
|
- *
|
|
|
- * The `id` property is used to prevent duplication of jobs,
|
|
|
- * while jobs with `user:true` need to be processed after
|
|
|
- * all internal jobs have been processed first.
|
|
|
- *
|
|
|
- * In most cases a job will actually be a Watcher instance
|
|
|
- * which implements the above interface.
|
|
|
+ * Reset the batcher's state.
|
|
|
*/
|
|
|
|
|
|
-function Batcher () {
|
|
|
- this.reset()
|
|
|
+function reset () {
|
|
|
+ queue = []
|
|
|
+ userQueue = []
|
|
|
+ has = {}
|
|
|
+ waiting = false
|
|
|
+ flushing = false
|
|
|
}
|
|
|
|
|
|
-var p = Batcher.prototype
|
|
|
+/**
|
|
|
+ * Flush both queues and run the jobs.
|
|
|
+ */
|
|
|
+
|
|
|
+function flush () {
|
|
|
+ flushing = true
|
|
|
+ run(queue)
|
|
|
+ run(userQueue)
|
|
|
+ reset()
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * Reset the batcher's state.
|
|
|
+ * Run the jobs in a single queue.
|
|
|
+ *
|
|
|
+ * @param {Array} queue
|
|
|
*/
|
|
|
|
|
|
-p.reset = function () {
|
|
|
- this.has = {}
|
|
|
- // we have two separate queues: one for directive updates
|
|
|
- // and one for user watcher registered via $watch().
|
|
|
- // we want to guarantee directive updates to be called
|
|
|
- // before user watchers so that when user watchers are
|
|
|
- // triggered, the DOM would have already been in updated
|
|
|
- // state.
|
|
|
- this.queue = []
|
|
|
- this.userQueue = []
|
|
|
- this.waiting = false
|
|
|
- this.flushing = false
|
|
|
+function run (queue) {
|
|
|
+ // do not cache length because more jobs might be pushed
|
|
|
+ // as we run existing jobs
|
|
|
+ for (var i = 0; i < queue.length; i++) {
|
|
|
+ queue[i].run()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -54,51 +60,21 @@ p.reset = function () {
|
|
|
* - {Function} run
|
|
|
*/
|
|
|
|
|
|
-p.push = function (job) {
|
|
|
- if (!job.id || !this.has[job.id] || this.flushing) {
|
|
|
+exports.push = function (job) {
|
|
|
+ if (!job.id || !has[job.id] || flushing) {
|
|
|
// A user watcher callback could trigger another
|
|
|
// directive update during the flushing; at that time
|
|
|
// the directive queue would already have been run, so
|
|
|
// we call that update immediately as it is pushed.
|
|
|
- if (this.flushing && !job.user) {
|
|
|
+ if (flushing && !job.user) {
|
|
|
job.run()
|
|
|
return
|
|
|
}
|
|
|
- var queue = job.user
|
|
|
- ? this.userQueue
|
|
|
- : this.queue
|
|
|
- queue.push(job)
|
|
|
- this.has[job.id] = job
|
|
|
- if (!this.waiting) {
|
|
|
- this.waiting = true
|
|
|
- _.nextTick(this.flush, this)
|
|
|
+ ;(job.user ? userQueue : queue).push(job)
|
|
|
+ has[job.id] = job
|
|
|
+ if (!waiting) {
|
|
|
+ waiting = true
|
|
|
+ _.nextTick(flush)
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Flush both queues and run the jobs.
|
|
|
- */
|
|
|
-
|
|
|
-p.flush = function () {
|
|
|
- this.flushing = true
|
|
|
- run(this.queue)
|
|
|
- run(this.userQueue)
|
|
|
- this.reset()
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Run the jobs in a single queue.
|
|
|
- *
|
|
|
- * @param {Array} queue
|
|
|
- */
|
|
|
-
|
|
|
-function run (queue) {
|
|
|
- // do not cache length because more jobs might be pushed
|
|
|
- // as we run existing jobs
|
|
|
- for (var i = 0; i < queue.length; i++) {
|
|
|
- queue[i].run()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-module.exports = Batcher
|
|
|
+}
|