Skip to content

Instantly share code, notes, and snippets.

@zeekay
Created December 7, 2012 22:28
Show Gist options
  • Save zeekay/4237058 to your computer and use it in GitHub Desktop.
Save zeekay/4237058 to your computer and use it in GitHub Desktop.
class AsyncBase
constructor: ->
@_queue = []
@_result = null
_add: (fn, args) ->
@_queue.push [fn, args]
end: (callback) ->
result = null
iterate = =>
if @_queue.length == 0
# return with last result
callback.apply @, [null].concat result
else
# pop off next method to execute
[fn, args] = @_queue.shift()
# pass along result of previous method call
if result?
args = args.concat result
result = null
# add callback to continue iteration
args.push ->
_args = Array.prototype.slice.call arguments
# check for error
err = _args.shift()
if err?
callback err
else
result = _args
iterate()
fn.apply @, args
iterate()
# makes an async function chainable
chainable = (fn) ->
->
args = Array.prototype.slice.call arguments
if typeof args[args.length-1] == 'function'
# Callback exists, don't queue up result.
fn.apply @, args
else
# Queue up method
@_add fn, args
@
class Test extends AsyncBase
numbers: []
number: chainable (number, callback) ->
@numbers.push number
callback null
add: chainable (callback) ->
result = 0
while n = @numbers.pop()
result += n
callback null, result
wait: chainable (callback) ->
setTimeout ->
callback null
, 1000
test = new Test()
test.number(4).number(5).wait().add().end (err, result) ->
console.log result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment