Created
August 28, 2012 22:34
-
-
Save MaxPower15/3504975 to your computer and use it in GitHub Desktop.
The "ready" pattern in coffeescript, distilled
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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 | |
@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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