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):
(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.
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):With this helper, we can just do something like:
(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 justconsole.error(err)
with aresolve()
instead ofreject(err)
. You can pick out the empty objects before returning.Cool!