Skip to content

Instantly share code, notes, and snippets.

@billyham
Last active September 6, 2016 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save billyham/f42d0323697553dc2466143ec7880898 to your computer and use it in GitHub Desktop.
Save billyham/f42d0323697553dc2466143ec7880898 to your computer and use it in GitHub Desktop.
batch.js with comments for documentation
// Copyright 2016
//
// Batch.js
//
// A Typical Useage:
// Parent creates a Batch object with or without 'sync'.
// Parent adds a job function to the queue stack.
// If no 'sync' and no current 'frame', a request will be made for an
// animation frame. It is assigned to the frame property.
// A global resource runs a requestAnimationFrame function to
// retrieve the next frame.
// Batch.run() is given as a callback to the global resource.
// When Batch.run is called, all the functions in the job queue fire in order.
// If Batch.sync evalutes to truthy, an external entity is
// responsible for calling request_frame().
// Signature:
// Batch(sync) -> <batch object>
//
// Properties:
// jobs
// sync
// frame
//
// Public Methods:
// request_frame() -> <function>
// queue(<function>) -> null
// add(<function>) -> null
// run() -> null
//
// Private Functions:
// requestAnimationFrame(callback) -> <animation frame>
module.exports = Batch
function Batch(sync) {
if(!(this instanceof Batch)) {
return new Batch(sync)
}
this.jobs = []
this.sync = sync
this.frame = null
// ERROR: this is redundant.
// this.run = this.run.bind(this)
}
Batch.prototype.request_frame = request_frame
Batch.prototype.queue = queue
Batch.prototype.add = add
Batch.prototype.run = run
// A job function is added which is given its caller as context.
// add() returns a queue() function.
// When queue() is called, Batch.queue is invoked with the job
// and it is added to the jobs array.
function add(fn) {
var queued = false
, batch = this
, self
, args
return queue
// The arguments passed into queue are saved to a new array
function queue() {
args = [].slice.call(arguments)
self = this
if(!queued) {
queued = true
batch.queue(run)
}
}
// The functions added to the jobs queue are given
// their caller as their context.
function run() {
queued = false
fn.apply(self, args)
}
}
// Pushes a job function onto the `jobs` array. If sync
// isn't present, it sends a request_frame call.
function queue(fn) {
this.jobs.push(fn)
if(!this.sync) {
this.request_frame()
}
}
// Executes all functions in the `jobs` queue.
function run() {
var jobs = this.jobs
this.jobs = []
this.frame = null
for(var i = 0, l = jobs.length; i < l; ++i) {
jobs[i]()
}
}
// Sends a requst that executes run() after receiving and saving
// the next animation frame. Performs no action if this.frame exists.
function request_frame() {
if(this.frame) {
return
}
this.frame = requestAnimationFrame(this.run)
}
// Attempts to request an animation frame. The resource is
// given run() as a callback. When no frame is provided,
// run() executes after a 1/60 sec. delay
function requestAnimationFrame(callback) {
var raf = global.requestAnimationFrame ||
global.webkitRequestAnimationFrame ||
global.mozRequestAnimationFrame ||
timeout
return raf(callback)
function timeout(callback) {
return setTimeout(callback, 1000 / 60)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment