For the love of Promises, stop nesting your chains.then()

I’ve been spending a lot of time in some express JS applications lately. I love express, but generally only when I can work with ES7 syntax.

However, lately I’ve been tackling deep, nested, unreadable promise chains.

app.use((req, res) => {
  runSomeDatabaseCode().then((response) => {
    const newResponse = response.manipulate();
    runSomeAPICode(newResponse).then((data) => {
      if (!data) throw new Error("It Broke");
      res.status(200).send(data)
    }).catch(err => res(500).send('Error'))
  }).catch(err => res(500).send('Error'))
});

For the love of all things asynchronous, please tidy this up. The solution in this instance is quite simple — linear promise chains.

app.use((req, res) => {
  new Promise(r => r()) // Just an empty promise to start the structure
  .then(() => new Promise((resolve, reject) => {
    runSomeDatabaseCode()
    .then(response => {
      const newResponse = response.manipulate();
      resolve(newResponse) // Pass the response to the next in the chain
    })
    .catch(error => {
      reject(error)
    })
  }))
  .then((newResponse) => new Promise((resolve, reject) => {
    runSomeAPICode(newResponse)
    .then(data => {
      if (!data) throw new Error('It Broke')
      resolve(data)
    })
  }))
  .then(data => {
    res.status(200).send(data); // resolve to express
  })
  .catch(err => {
    res.status(500).send(err); // resolve errors to express
  })
})

These linear structures are much better as they free up the scope for your functions, remove unnecessary repetition in code and generally allow a better reading experience with less left-right scrolling.

For other cool Promise-related stuff, check out Bluebird. Developers will thank you for it when they are reading your beautifully structured code.

 
1
Kudos
 
1
Kudos

Now read this

Using Web Workers to run JavaScript in parallel

JavaScript, in the browser, runs in a single thread. This is fine, and works fairly well for most websites. However, when running large, complex tasks or long scripts, it makes the webpage unresponsive. The best way to speed up these... Continue →