DEV Community

Cover image for A quick guide to JavaScript Promises

A quick guide to JavaScript Promises

Dominik Kundel on June 12, 2017

When you are writing JavaScript, callbacks are one of the most confusing concepts. Promises are the new approach to improve working with async code...
Collapse
 
justsml profile image
Daniel Levy

Excellent article, I only have one suggestion.
Avoid using either .forEach or .reduce for sequential promise execution - at least when overwriting references to the promises.

Either use plain function recursion, or use a lib like bluebird.

Bluebird has features builtin for exactly this situation, including .mapSeries and concurrent execution limits, like .map(fn, {concurrency: CPU_COUNT})

Example with Bluebird:


const Promise = require('bluebird')

const searchTerms = (terms) => Promise
  .resolve(terms)
  .map(q => `http://httpbin.org/get?${q}`) // transform to needed func params for next step(s)
  .tap(url => console.time('Load %s', url)) // Easy to add/remove metrics
  .mapSeries(url => fetch(url) // -> Nested dependent logic:
    .then(resp => resp.json()) // unpack JSON
    .then(resp => { // Final step
      let url = resp.url;
      console.timeEnd('Load %s', url);
      return resp.url; // {url: resp.url, body: resp.body};
    })
  )

searchTerms(['ahoy', 'hello', 'hallo'])
  .then(allUrls => {console.log('Successfully loaded URL(s):', allUrls))
  .catch(error => console.error('A call failed:', error.message))

Collapse
 
justsml profile image
Daniel Levy

Also, another example of bluebird features, promisify existing callback-based libs using a common method.

So to read a file w/ Promises, use:

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readFileAsync('/etc/hosts')
.then(content => {
  console.log('File content:', content);
}).catch(err => {
  console.error('An error occurred reading this file.', err.message);
});

Collapse
 
dkundel profile image
Dominik Kundel

Good point! I mainly wanted to explain how to handle it without the help of an additional tool in a still elegant solution. I think a recursive function wouldn't make it too readable. But yeah I agree that you should ideally use something that is a bit more sophisticated. Bluebird is certainly a good solution for this.

Collapse
 
carlflor profile image
Carl Flor

Thanks for this! Great article! :)

Collapse
 
dkundel profile image
Dominik Kundel

Thank you! :)

Collapse
 
oneearedmusic profile image
Erika Wiedemann

Fantastic article, thanks! Shared around the office

Collapse
 
dkundel profile image
Dominik Kundel

Thanks a lot! :)

Collapse
 
jess profile image
Jess Lee

THANK YOU!

Collapse
 
dkundel profile image
Dominik Kundel

Glad you enjoyed it :)

Collapse
 
rpalo profile image
Ryan Palo

This is amazing! This is exactly what I needed, thank you. 😬