async2

Better async utilities for node and the browser

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.

5  thoughtful single-chain
7  order of operations
5  escape callback hell!

Partially backward-compatible with async.js:

async.series [
 -> async.delay 100@
 -> async.delay 50@
]->
  assert.closeTo 100+50since(start)25
 
  async.parallel [
   -> async.delay 100@
   -> async.delay 50@
  ]->
    assert.closeTo (100+50)+100since(start)25
    done()

But better thanks to several improvements:

async
  .serial((next) ->
    assert.typeOf next'function'
    next null'async data' # e.g., fs.readFile(), or jQuery.ajax() 
  )
  .parallel((data, next) ->
    assert.equal data'async data'
    assert.typeOf next'function'
    next null
  )
  .parallel((data, next) ->
    assert.equal data'async data'
    assert.typeOf next'function'
    next null
  )
  .serial(->
    assert.typeOf @'function' # `this` === `next` 
    @ null123456
  )
  .end (err, results...) ->
    assert.equal errnull
    assert.deepEqual results[ 123456 ]
    done()

In fact, way better:

flow = new async
for i in [1..10]
  ((i) ->
    method = if i%3 then 'parallel' else 'serial' # an overcomplicated display of flexibility 
    flow[method(next) ->
      async.delay 25->
        console.log "#{method} #{i}"
        next()
  )(i)
flow.go (err, results...) ->
  console.log '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 = false
async
  before: ->
    #loading.show() 
    called = true
  do: (next) ->
    # main logic 
    assert.ok called
    next 'err''result'
  error: (err) ->
    assert.equal 'err''err'
    #alert err 
  success: (result) ->
    assert false'success() should not have been called here'
    #console.log data 
  complete: (err, result) ->
    assert.equal err'err'
    assert.equal result'result'
    #loading.hide() 
    done()

Exhibit B: How about to you JavaScript developers?

called = false
async
  .try(->
    @ new Error 'thrown node cb style'
  )
  .catch((err) ->
    called = true
    assert.equal ''+err'Error: thrown node cb style'
  )
  .finally (err, result) ->
    assert.ok called
    assert.equal ''+err'Error: thrown node cb style'
    assert.typeOf result'undefined'
    done()

Exhibit C: Any Rubists in the audience?

called = false
async
  .begin(->
    @ new Error 'thrown node cb style'
  )
  .rescue((err) ->
    called = true
    assert.equal ''+err'Error: thrown node cb style'
  )
  .else((result) ->
    console.log 'Else'
    assert false'else() should not have been called here'
  )
  .ensure (err, result) ->
    assert.ok called
    assert.equal ''+err'Error: thrown node cb style'
    assert.typeOf result'undefined'
    done()

Additionally, nextTick() users will appreciate the lazy man's grouped blocking serial execution:

async.push 'A'(next) ->
  setTimeout (-> console.log 'second'; next())100
async.push 'B'(next) ->
  setTimeout (-> console.log 'first'; next())10
async.push 'A'(next) ->
  setTimeout (-> console.log 'third'; next())1
# 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.

  • 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...

  • 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