8

I want to know which of the two methods are better when dealing with asynchronous code in JavaScript. I want to understand which method leads to cleaner code. I'm used with promises and they seem more flexible than the async approach (https://github.com/caolan/async).

I also know about the Task.js library (http://taskjs.org/), but this relies on the yield keyword which is part of Ecmascript Harmony.

2
  • 2
    The main advantage of using the async library linked is that it wraps/provides a number of common operations in an async style. While "plain" Promises (i.e. jQuery.Deferred) can be used, it would take much more boilerplate (if one of those operations is desired in an async style) as you'd effectively have to write your own versions of said functions. The async library linked and Promises ultimately work the same way - a callback is used. Commented Mar 19, 2013 at 2:48
  • 3
    What I like about promises is that you return something from a function, instead accepting a callback which you will call later (for me it's like saying: I can't return this value to you in this moment, but I promise you that you will get a value). What I don't like is that you have to pass 2 functions, but this will be resolved when EcmaScript Harmony will be ready. Given the fact that Task.js is so awesome, promises are really future proof. Maybe it will be interesting to develop a module that closes the gap between promises and callbacks (something like async, but returning a promise). Commented Mar 20, 2013 at 21:56

4 Answers 4

11

The async library encapsulates a couple of very common asynchronous patterns, including making arbitrary async calls in parallel and iterating over a list asynchronously. It's designed to work with "nodeback" (err, res) APIs, which makes it useful for a lot of Node.js applications. async is however a specific solution, and it only simplifies the async patterns included in the library.

Promises, by contrast, are in my opinion a much more general solution to the problem of asynchronous code. Not only do they provide the obvious benefits at first glance of error-bubbling and of flattening callback pyramids, problems that would otherwise require the sorts of complex patterns async encapsulates can be solved much more simply.

I'll demonstrate this with a quick tour through some of async's available patterns. For instance, the async.waterfall function is used something like this:

async.waterfall([
      function (cb) {
        asyncCall('argument', cb);
      },
      function(resultOfFirstCall, cb) {
        anotherCall(resultOfFirstCall, 'someOtherArgument' cb);
      },
    ], function(err, res) {
      if (err) handle(err);
      useFinalResult(res);
    });

There's no equivalent to async.waterfall in most promise libraries (or at least there isn't one in Q), because it's so simple to implement it from scratch using Array.reduce, like so (example based on Q but pretty much the same on other promise libraries):

[
  function() {
    return asyncCall('argument');
  },
  function(resultOfFirstCall) {
    return anotherCall(resultOfFirstCall, 'someOtherArgument');
  }
].reduce(Q.when, Q())
 .then(useFinalResult, handle);

The other big functions in async include async.parallel, which Q includes as Q.all:

// async
async.parallel([
    asyncFunc,
    asyncFunc2
    ], function(err, res) {
      if (err) handle(err);
      useFinalResult(res);
      // res[0] === asyncFuncResult
      // res[1] === asyncFunc2Result
    });
// Q
Q.all([
  asyncFunc(),
  asyncFunc2()
]).then(useFinalResult, handle);

And async.map. You actually don't need async.map when you're using promises, because the normal Array.map is sufficient:

// async
async.map(['file', 'file2', 'file3'], fs.stat, function(err, res) {
  if (err) handle(err);
  useFinalResult(res);
});
// Q
Q.all(['file', 'file2', 'file3']
  .map(Q.nfbind(fs.stat)))
  .then(useFinalResult, handle);

The rest of async is similarly easy to implement concisely, using relatively simple pieces of your promise library. (Note that that last example used a function Q.nfbind: nfbind and the other nf* functions Q provides are basically all you need to use promises with nodeback APIs, so there isn't even a particularly big impedance trying to use promises with libraries that expect nodebacks.)

In the end, whether you use promises or nodebacks is up to you, but I think promises are a much more flexible, capable, and generally concise way to implement most all asynchronous operations.

Callbacks are imperative, promises are functional is worth a read for more information in this general vein.

Sign up to request clarification or add additional context in comments.

Comments

3

Since you tagged your question with node, I'd recommend the async library. The control flow functions are great to work with and eliminate the ugly and hard to follow callback chains. The API is setup really nice for injecting callbacks that follow node's signature (error, result) into the control functions. It's basically included by default in almost all node scripts I write.

While you can use async for client-side as well, it's probably unnecessary for most projects. jQuery includes promises, and you can accomplish the same thing with them.

Comments

1

I think promise/a and async lib with difference targets, promise focus on one step async operation progress, and async focus on multi step async operate, for node, async has a wilder use for a lot of async apis.

by the way, to deal with async operations, use named function instead of Anonymous functions will be the most effective way

Comments

0

gumballhead recommended async.js, but i would recommend using Parse Cloud Code if you're working with Node. Their API has promises built right in, along with other goodies (like a database). It saves time and you don't have to worry about backend stability. You can include any NPM module with a little tweak of module.exports to just exports. It also integrates seamlessly with your frontend! I've been having success with this approach on my current project and just wanted to comment with a new approach.

Feel free to comment with any reasons why/when you should not use Cloud Code; for I have had no such experience yet.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.