public
Created — forked from tcr/async.coffee

Serial/Parallel functions in CoffeeScript

  • Download Gist
async.coffee
CoffeeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
# Asynchronous DSL for CoffeeScript
 
serial = (f) ->
next = -> arr.shift().apply(null, arguments) if arr.length
arr = (v for k, v of f(next))
next()
null
 
parallel = (f, after = ->) ->
res = {}; arrc = 0
arrc++ for k, v of f
for k, v of f
do (k, v) ->
v (args...) ->
res[k] = args
if not --arrc then after(res)
null
 
#########################
# 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)
 
# serial accepts a function with one "next" continuation,
# which returns a list of steps to execute in order
# you can label your steps anything, but numbers look good:
 
serial (next) ->
1: -> fs.open('file', 'w', next)
2: (err, f) -> fs.write(f, 'Apples', (a...) -> next(a..., f))
3: (err, written, f) -> fs.close(f, next)
last: -> console.log 'Serial test complete.'
 
##############################
# parallel test with timeouts
 
console.log('Waiting for parallel test...')
 
# parallel accepts a list of steps to execute in any order
# (each step is passed a "done" continuation to call when finished)
# and an (optional) last function to call with results of each step
 
parallel
A: (done) -> setTimeout((-> done(new Date)), 1000)
B: (done) -> setTimeout((-> done(new Date)), 3000)
C: (done) -> setTimeout((-> done(new Date)), 2000)
(res) -> console.log 'Parallel results:', JSON.stringify(res)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.