UNPKG

silk-gui

Version:

GUI for developers and Node OS

94 lines (85 loc) 2.02 kB
var _ = require('./util') var MAX_UPDATE_COUNT = 10 // 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 /** * Reset the batcher's state. */ function reset () { queue = [] userQueue = [] has = {} waiting = false flushing = false } /** * Flush both queues and run the jobs. */ function flush () { flushing = true run(queue) run(userQueue) 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() } } /** * Push a job into the job queue. * Jobs with duplicate IDs will be skipped unless it's * pushed when the queue is being flushed. * * @param {Object} job * properties: * - {String|Number} id * - {Function} run */ exports.push = function (job) { var id = job.id if (!id || !has[id] || flushing) { if (!has[id]) { has[id] = 1 } else { has[id]++ // detect possible infinite update loops if (has[id] > MAX_UPDATE_COUNT) { _.warn( 'You may have an infinite update loop for the ' + 'watcher with expression: "' + job.expression + '".' ) return } } // 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 (flushing && !job.user) { job.run() return } ;(job.user ? userQueue : queue).push(job) if (!waiting) { waiting = true _.nextTick(flush) } } }