Last Updated: March 08, 2016
·
7.373K
· Ionut-Cristian Florescu

Elegant asynchronous control flow with IcedCoffeeScript

Writing Node.js code to interact with external services (databases, email, http, etc.) can easily turn into a cumbersome "callback hell".

While there are a number of async control modules out there, such as the excellent async, most of them might be a bit overkill for the most common usage patterns.

However, if you're not a JavaScript purist and you care for code readability and development speed, IcedCoffeeScript can spare you an incredible amount of trouble.

Asynchronous flow in IcedCoffeeScript

Here's just a quick real-world example - the code comes from LeasingSH.ro, a project built entirely in Node.js:

method: 'get'
route: ///
  -
  (
    [A-Z]
    [A-Z|\d]{2}
    \d{5}
  )
  \.html$
///

callback: (req, res, next) ->
  [ uid ] = req.params
  query = Product.findOne uid: uid

  if req.isAuthenticated() and req.user.isSalesman
    query.populate
      path:   'dealer'
      select: 'name phone email address'

  await query.lean().exec defer err, product; return next err if err or not product?

  categoryKey = product.category.key

  errors = {}
  await
    helpers.loadSpecialProducts categoryKey, 10, defer errors.specialProducts, specialProducts

    Product.find()
      .select('uid make model price year').slice('pictures', 1)
      .where('isActive').equals(yes)
      .where('isSold').equals(no)
      .where('category.key').equals(categoryKey)
      .limit(5)
      .lean().exec defer errors.suggestedProducts, suggestedProducts

  for own operation, err of errors
    return next err if err

  res.render 'public/product', {
    pageType: 'product'
    product
    specialProducts, suggestedProducts
  }

After waiting to read the product information, we're executing two parallel queries to read additional information (special & suggested products).

It really can't get any easier than this...

The beauty of combining Node.js with IcedCoffeeScript is that you're really getting the best of two worlds:

  • The speed and ability to handle concurrent connections characteristic to Node.js - due to its event-based nature, the server can process something else (i.e. another incoming request) while waiting for a background operation to complete;
  • The readability and concision of CoffeeScript (similar to Ruby's), enhanced even more by IcedCoffeeScript's elegant way of dealing with callbacks.

2 Responses
Add your response

Thanks Lonut for a nice post introducing icedCoffeeScript,

I have read the other posts from you as well but in my opinion, JS world is chaotic. JS is not beautiful and coffeescript is. But still, people will find it confused working with JS especially beginner, since the other language they fix and enhance their language in its core.

I love JS, but still it's chaotic for me. I'm looking into Dart to see if this world can be better :)

over 1 year ago ·

Hi Dung Quang,

Thanks for reading. Yep, after 15 years of stillness, the JS world is evolving fast and IT IS chaotic. But so is most of the world nowadays, isn't it? :-)

Totally agree about CoffeeScript bringing beauty and and concision. By the way, there's a great short book on CS, you probably know about it already, but other people might not, so I'll post the link here: http://arcturo.github.io/library/coffeescript/

Dart looks promising and - referring strictly to the language, it has everything JS is missing. But he whole Internet has to catch up with it, so in my opinion we're won't see wide-spread adoption for 5 years to say the least...

over 1 year ago ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip