DEV Community

Discussion on: A quick guide to JavaScript Promises

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
 
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
 
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);
});