DEV Community

Async Iteration in Nodejs

Kwabena Bio Berko on October 17, 2017

Node.js is an amazing JavaScript run-time environment, no doubt. Its non-blocking IO model makes applications built with it amazingly fast and high...
Collapse
 
lucretius profile image
Robert Lippens • Edited

Nice! This one has snuck up on me (and I'd wager most javascript developers) more often than I'd like to admit. Javascript's non-blocking I/O is nice but can be a bit counter-intuitive for async operations.

I've become a big fan of doing operations like this which can be done in parallel using something like Promise.all over callbacks. (I actually use generators most of the time, as the project I work on has issues upgrading past node v6 - but async/await would work great as Ryan mentioned)

I would wrap the findById in a Promise (I do this manually but something like BluebirdJS can handle entire libraries if you are dealing with old node packages):

const findById = (userId) => {
  return new Promise((resolve, reject) => {
    User.findById(userId, (err, user) => {
       if (err)  {
         reject(err);
       } else {
         resolve({
          firstName: user.firstName,
          lastName: user.lastName,
          email: user.email
         });
    });
  });
}

With this helper, we can just do something like:

return Promise.all(ids.map((id) => findById(id)));

(where our caller would use the result of the promise.)

Note that with Promise.all, a single rejection will terminate the entire call, so if you can tolerate partial results, I recommend just console.error(err) with a resolve() instead of reject(err). You can pick out the empty objects before returning.

Collapse
 
kwabenberko profile image
Kwabena Bio Berko

Cool!

Collapse
 
ryhenness profile image
Ryan

Hey Kwabena, it’s funny that you posted this today because I posted my solution to the async problem as well today πŸ˜‚ I like the creative counter approach that you used. You might be able to benefit from Promises and Async/Await! I talk about them in my last article: dev.to/ryhenness/the-path-to-conqu...

Collapse
 
mrm8488 profile image
Manuel Romero
if(error) return callback(error)

If there is no error:

return callback(null, userInfoArr)

When working with callbacks is important error first management