Skip to content

Instantly share code, notes, and snippets.

@MaxPower15
Created August 28, 2012 22:34
Show Gist options
  • Save MaxPower15/3504975 to your computer and use it in GitHub Desktop.
Save MaxPower15/3504975 to your computer and use it in GitHub Desktop.
The "ready" pattern in coffeescript, distilled
#
# myObject = new MyObject();
# myObject.ready = readyMixin;
# myObject.asyncInit(function(){ myObject.ready(true); });
#
# myObject.ready(function() {
# console.log("I'm ready now!");
# });
#
# myObject.ready(function() {
# this.doSomething(); // this === myObject
# });
#
# myObject.ready("doSomethingElse", param1, param2);
#
readyMixin = (callback, args...) ->
# Initialize the queue if necessary.
@_readyQueue = [] unless @_readyQueue
# Calling myObject.ready(true) changes the ready state to true and
# executes all queued callbacks.
@_isReady = true if callback is true
# Calling myObject.ready(false) sets the ready state to false. All
# subsequent callbacks will be queued until ready(true) is called.
@_isReady = false if callback is false
if @_isReady
if !@_readyLock
# If the queue isn't already being executed, then pop and execute in
# order. If it's already ready, push the callback, then immediately
# pop and execute in the same manner.
@_readyQueue.push { callback: callback, args: args } if callback && callback isnt true
@_readyLock = true
for func in @_readyQueue
if func? && func.callback?
if typeof func.callback is "string"
@[func.callback].apply @, func.args
else
func.callback.apply @, func.args
@_readyQueue = []
@_readyLock = false
else
# The queue is already being executed, so just immediately execute
# this function. This saves us from infinite recursive loops.
if typeof callback is "string"
@[callback].apply @, args
else
callback.apply(@, args) if callback
else
# Queue the callback.
@_readyQueue.push { callback: callback, args: args } if callback && callback isnt true
@
var readyMixin;
var __slice = Array.prototype.slice;
readyMixin = function() {
var args, callback, func, _i, _len, _ref;
callback = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
if (!this._readyQueue) {
this._readyQueue = [];
}
if (callback === true) {
this._isReady = true;
}
if (callback === false) {
this._isReady = false;
}
if (this._isReady) {
if (!this._readyLock) {
if (callback && callback !== true) {
this._readyQueue.push({
callback: callback,
args: args
});
}
this._readyLock = true;
_ref = this._readyQueue;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
func = _ref[_i];
if ((func != null) && (func.callback != null)) {
if (typeof func.callback === "string") {
this[func.callback].apply(this, func.args);
} else {
func.callback.apply(this, func.args);
}
}
}
this._readyQueue = [];
this._readyLock = false;
} else {
if (typeof callback === "string") {
this[callback].apply(this, args);
} else {
if (callback) {
callback.apply(this, args);
}
}
}
} else {
if (callback && callback !== true) {
this._readyQueue.push({
callback: callback,
args: args
});
}
}
return this;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment