Skip to content

Instantly share code, notes, and snippets.

@tcr
Forked from walling/async.coffee
Created July 19, 2011 05:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcr/1091402 to your computer and use it in GitHub Desktop.
Save tcr/1091402 to your computer and use it in GitHub Desktop.
Lean and Mean Serial function in CoffeeScript
# Lean and Mean Serial/Parallel DSL for CoffeeScript
# - based of https://gist.github.com/1090670 by timcameronryan,
# https://gist.github.com/1091019 by walling
serial = (spec) ->
steps = (func for key, func of spec when key != 'catch')
next = (err, args...) ->
return spec.catch(err) if err
steps.shift().apply(next, args) if steps.length > 0
next null
return
parallel = (spec, after = ->) ->
res = {}; stepc = 0; steps = {}
for key, step of spec when key not in ['catch', 'finally']
steps[key] = step
stepc++
for key, step of steps
do (key, step) -> step.apply (err, args...) ->
return spec.catch(err) if err
res[key] = args
if --stepc == 0 then spec.finally(res)
return
#########################
# serial test w/ mock fs
fs =
open: (_, _, cb) -> console.log('[fs.open]'); cb(0, {a_fake: 'file object'})
write: (f, _, cb) -> console.log('[fs.write]', f); cb(0, f)
close: (f, cb) -> console.log('[fs.close]', f); cb(0, f)
read: (f, cb) -> console.log('[fs.read]', f); cb(new Error 'not readable')
# Serial accepts a list of steps to execute in order.
# Use @/this as continuation and local storage.
# You can label your steps anything, but numbers look good:
serial
1: -> fs.open 'file', 'w', @
2: (@f) -> fs.write f, 'Apples', @
3: (written) -> fs.close @f, @
4: -> console.log 'Serial write test complete.'
catch: (err) ->
console.log "Write test failed: #{err.stack}"
# Example with failure:
serial
1: -> fs.open 'file', 'w', @
2: (@f) -> fs.read f, @
3: (read) -> fs.close @f, @
4: -> console.log 'Serial read test complete.'
catch: (err) ->
console.log "Serial read test failed: #{err.stack}"
##############################
# parallel test with timeouts
console.log('Waiting for parallel test...')
delay = (ms, f) -> setTimeout f, ms
# Parallel accepts a list of steps to execute in any order
# Use @/this as continuation and local storage.
# Add catch function for errors, and a finally function for returned results.
parallel
A: -> delay 5000, => console.log('A ran.'); @(0, new Date)
B: -> delay 1000, => console.log('B ran.'); @(0, new Date)
C: -> delay 3000, => console.log('C ran.'); @(0, new Date)
catch: (err) ->
console.log "An error occurred: #{err.stack}"
finally: (res) ->
console.log 'Parallel results:', JSON.stringify(res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment