Async2.js
Better asynchronous javascript flow control in 132 lines (5.7KB) or 4KB minified or 1285 bytes gzipped.
Inspired by async, mini-async, Mocha, Chai, Should.js, and IcedCoffeeScript/TameJs libraries.
Flow Control
- new / flow / with : optional chainable instantiator; receives beginning result; useful in series
- beforeAll / before : non-blocking function called once before first task
- beforeEach : non-blocking function called once before each task
- serial / series / blocking / waterfall : blocking function called in order; results always waterfalled
- parallel / nonblocking : non-blocking function called in order
- do / then / try / begin / start / auto : optionally blocking function called in order; determined by length of arguments callback expects
- afterEach / between / inbetween : non-blocking function called once after each task
- error / catch / rescue : blocking function called when error occurs
- success / else : non-blocking function called after all tasks have completed, but only if no errors occur
- end / finally / ensure / afterAll / after / complete / done / go : blocking function called after all tasks have completed
- whilst : provide test, iterator, and callback functions. will iterate until test passes, then execute callback
- delay : inverts argument order to
setTimeout()
for easier CoffeeScript markup - push / nextTickGroup : serially-queued automatic-kick-start execution like
nextTick()
orsetTimeout(f,0)
, but grouped
Quick Examples
First, reflect upon our haiku mantra:
5 thoughtful single-chain
7 order of operations
5 escape callback hell!
Then, observe in action:
Partially backward-compatible with async.js:
asyncseries -> asyncdelay 100@ -> asyncdelay 50@-> assertcloseTo 100+50sincestart25 asyncparallel -> asyncdelay 100@ -> asyncdelay 50@ -> assertcloseTo 100+50+100sincestart25 done
But better thanks to several improvements:
async serial asserttypeOf next'function' next null'async data' # e.g., fs.readFile(), or jQuery.ajax() parallel assertequal data'async data' asserttypeOf next'function' next null parallel assertequal data'async data' asserttypeOf next'function' next null serial-> asserttypeOf @'function' # `this` === `next` @ null123456 end assertequal errnull assertdeepEqual results 123456 done
In fact, way better:
flow = for i in 1..10 method = if i%3 then 'parallel' else 'serial' # an overcomplicated display of flexibility flowmethod asyncdelay 25-> consolelog " " next iflowgo consolelog 'try this in async.js!' done
It really makes you wonder: how long have we needed a good asynchronous flow control library, and not known it?
Exhibit A: Look familiar to any jQuery.ajax() developers?
called = falseasync : -> #loading.show() called = true : # main logic assertok called next 'err''result' : assertequal 'err''err' #alert err : assert false'success() should not have been called here' #console.log data : assertequal err'err' assertequal result'result' #loading.hide() done
Exhibit B: How about to you JavaScript developers?
called = falseasync try-> @ 'thrown node cb style' catch called = true assertequal ''+err'Error: thrown node cb style' finally assertok called assertequal ''+err'Error: thrown node cb style' asserttypeOf result'undefined' done
Exhibit C: Any Rubists in the audience?
called = falseasync begin-> @ 'thrown node cb style' rescue called = true assertequal ''+err'Error: thrown node cb style' else consolelog 'Else' assert false'else() should not have been called here' ensure assertok called assertequal ''+err'Error: thrown node cb style' asserttypeOf result'undefined' done
Additionally, nextTick()
users will appreciate the lazy man's grouped blocking serial execution:
asyncpush 'A' setTimeout -> consolelog 'second'; next100asyncpush 'B' setTimeout -> consolelog 'first'; next10asyncpush 'A' setTimeout -> consolelog 'third'; next1# outputs: # first # second # third
These are just a few of all the things it can do.
For the latest examples, review the easy-to-follow ./test/test.coffee.
Or try it immediately in your browser with codepen.
FAQ
-
great another high horsed coffeescripter! i just prefer to author in coffee. the .js and .js.min versions are in here too. you can do all the same things; in fact it is partially backward-compatible with async.js but in less lines of .js less bytes i should say; its a minimalist implementation with some improvements.
-
have you tried pull requests to the async repo? i may if i get positive response but its 100% refactor from ground-up; its not just a pull request. also any snide remarks are meant to encourage spirited but constructive debate. i'm not trying to be divisive. just had a need with a short timeline :) i know a lot of people get used to the way things are...
TODO
-
i could name variables better to assist with minification but its already pretty small. i may do it later though.
-
potential node.js madness: each series becomes its own cpu thread, each parallel becomes its own gpu thread.
"GPUs have evolved to the point where many real-world applications are easily implemented on them and run significantly faster than on multi-core systems. Future computing architectures will be hybrid systems with parallel-core GPUs working in tandem with multi-core CPUs.' -- Professor Jack Dongarra, Director of the Innovative Computing Laboratory, The University of Tennessee