create account

How to escape Promise Hell by pyrolistical

View this thread on: hive.blogpeakd.comecency.com
· @pyrolistical · (edited)
$0.02
How to escape Promise Hell
Unlike [Callback Hell](http://stackabuse.com/avoiding-callback-hell-in-node-js/), Promise Hell is accidentally self inflicted. Promise Hell is just a lack a familiarity with Promises.

This article will show some Promise Hell scenarios and the steps out get of it. All code snippets are written [ECMAScript 2015](https://github.com/lukehoban/es6features).

### Nested.then(..) with linearly dependent Promises
A typical example is Promises that depend on each other. Let’s say we have 3 Promises that depend on each other linearly: `fetchBook()`, `formatBook(book)`, and `sendBookToPrinter(book)`. The naïve code is:

```
fetchBook()
  .then((book) => {
    return formatBook(book)
      .then((book) => {
        return sendBookToPrinter(book);
      });
  });
```
The nesting is unnecessary, which simplies the code to:

```
fetchBook()
  .then((book) > {
    return formatBook(book);
  })
  .then((book) => {
    return sendBookToPrinter(book);
  });
```

Since these are single liners, the curly braces and return can be omitted.
```
fetchBook()
  .then((book) => formatBook(book))
  .then((book) => sendBookToPrinter(book));
```
But then we notice we have an identity closure! We can just inline the function:
```
fetchBook()
  .then(formatBook)
  .then(sendBookToPrinter);
```
### Nested .then(..) with independent Promises
In another scenario, we might have Promises that can be run independently. Let’s say we have 3 functions that return Promises: `demandMoreDonuts()`, `greet(name)`, and `closeGate()`. The naïve code would be:
```
demandMoreDonuts()
  .then(() => {
    return greet('fred')
      .then(() => {
        return closeGate();
      });
  });
```
How to get out of this situation depends if we care that these Promises are run in serial or in parallel. If we don’t care about the order of the Promises, then this can be simplified to:
```
Promise.all([
  demandMoreDonuts(),
  greet('fred'),
  closeGate()
]);
```
If we want to serialize the Promise order (say we want to abort early on error), then we can write this as:
```
demandMoreDonuts()
  .then(() => greet('fred'))
  .then(closeGate);
```
### Nested.then(..) with multiple dependent Promises
This situation is what most people get hung up on with Promises. In this example, let’s say we have 4 Promises: `connectDatabase()`, `findAllBooks(database)`, `getCurrentUser(database)`, and `pickTopRecommendation(books, user)`. The naïve code is:
```
connectDatabase()
  .then((database) => {
    return findAllBooks(database)
      .then((books) => {
        return getCurrentUser(database)
          .then((user) => {
            return pickTopRecommendation(books, user);
          });
      });
  });
```
Naïvely we will think this is the best we can do. How else can we get a reference to books and user at the same time? This code also has other issues, such as when we call `getCurrentUser(database)`, we have books unnecessarily in scope. The solution is to understand Promises can be held in a reference. We can extract the common bits out.
```
const databasePromise = connectDatabase();

const booksPromise = databasePromise
  .then(findAllBooks);

const userPromise = databasePromise
  .then(getCurrentUser);

Promise.all([
  booksPromise,
  userPromise
])
  .then((values) => {
    const books = values[0];
    const user = valuess[1];
    return pickTopRecommentations(books, user);
  });
```
**But wait**, doesn’t this mean we connect to the database twice? We call `.then(..)` on `databasePromise` twice! *This is a key thing to understand about Promises, they are only ever resolved once per creation.* This means you can call `.then(..)` as many times as you want, and you’ll only ever get one database connection. This is not the case if you call `connectDatabase()` multiple times.

The extraction of the values out of promises is a bit ugly. It can be simplifed using the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator), but this is only available in Node.js 5.x or greater.
```
Promise.all([
  booksPromise,
  userPromise
])
  .then((values) => pickTopRecommentations(...values));
```
… or with [destructuring](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), but this is only available in Node.js 6.x or greater.
```
Promise.all([
  booksPromise,
  userPromise
])
  .then(([books, user]) => pickTopRecommentations(books, user));
```
Alternatively it can be simplified with [Ramda](http://ramdajs.com)’s [apply](http://ramdajs.com/0.19.0/docs/#apply).
```
Promise.all([
  booksPromise,
  userPromise
])
  .then(R.apply(pickTopRecommentations));
```
Much more complex examples can be formed using a combination of these scenarios. I hope this will help somebody escape Promise Hell. If you have more specific examples that I have not covered, feel free to [tweet me](https://twitter.com/pyrolistical).

This article was originally posted on [Medium](https://medium.com/@pyrolistical/how-to-get-out-of-promise-hell-8c20e0ab0513#.mthxn9iwr) and I am the original author ([proof](https://twitter.com/pyrolistical/status/758133796755546112)).  @cheetah I have my eye on you.
👍  , , , , , , , , , ,
properties (23)
authorpyrolistical
permlinkhow-to-escape-promise-hell
categoryjavascript
json_metadata{"tags":["javascript","programming","promises"],"users":["cheetah"],"links":["http://stackabuse.com/avoiding-callback-hell-in-node-js/"]}
created2016-07-27 02:55:03
last_update2016-07-27 03:10:48
depth0
children7
last_payout2016-08-26 15:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.022 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length5,179
author_reputation665,138,270
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id392,823
net_rshares42,705,092,933
author_curate_reward""
vote details (11)
@cheetah ·
Hi! I am a content-detection robot. This post is to help manual curators; I have NOT flagged you.
Here is similar content:
https://medium.com/@pyrolistical/how-to-get-out-of-promise-hell-8c20e0ab0513
NOTE: I cannot tell if you are the author, so ensure you have proper verification in your post (or in a reply to me), for humans to check!
👍  ,
properties (23)
authorcheetah
permlinkre-how-to-escape-promise-hell-20160727t025548
categoryjavascript
json_metadata""
created2016-07-27 02:56:03
last_update2016-07-27 02:56:03
depth1
children3
last_payout2016-08-26 15:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length338
author_reputation942,693,160,055,713
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id392,834
net_rshares2,100,927,662
author_curate_reward""
vote details (2)
@pyrolistical ·
proof is at end of post
properties (22)
authorpyrolistical
permlinkre-cheetah-re-how-to-escape-promise-hell-20160727t025548-20160727t030523985z
categoryjavascript
json_metadata{"tags":["javascript"]}
created2016-07-27 03:05:24
last_update2016-07-27 03:05:24
depth2
children2
last_payout2016-08-26 15:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length23
author_reputation665,138,270
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id392,976
net_rshares0
@anyx ·
!cheetah whitelist
properties (22)
authoranyx
permlinkre-pyrolistical-re-cheetah-re-how-to-escape-promise-hell-20160727t025548-20160727t030705311z
categoryjavascript
json_metadata{"tags":["javascript"]}
created2016-07-27 03:07:06
last_update2016-07-27 03:07:06
depth3
children1
last_payout2016-08-26 15:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length18
author_reputation98,676,136,100,181
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id393,005
net_rshares0
@pyrolistical · (edited)
how do you make greater than show up properly in markdown reformatted code?  the site is auto converting to > to >

I did a bad thing.  I used mimic and replaced > with >
properties (22)
authorpyrolistical
permlinkre-pyrolistical-how-to-escape-promise-hell-20160727t030627638z
categoryjavascript
json_metadata{"tags":["javascript"]}
created2016-07-27 03:06:27
last_update2016-07-27 03:22:24
depth1
children0
last_payout2016-08-26 15:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length183
author_reputation665,138,270
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id392,993
net_rshares0
@steemitboard ·
Congratulations @pyrolistical! You have received a personal award!

[![](https://steemitimages.com/70x70/http://steemitboard.com/@pyrolistical/birthday2.png)](http://steemitboard.com/@pyrolistical)  2 Years on Steemit
<sub>_Click on the badge to view your Board of Honor._</sub>


> Do you like [SteemitBoard's project](https://steemit.com/@steemitboard)? Then **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
authorsteemitboard
permlinksteemitboard-notify-pyrolistical-20180725t220847000z
categoryjavascript
json_metadata{"image":["https://steemitboard.com/img/notify.png"]}
created2018-07-25 22:08:45
last_update2018-07-25 22:08:45
depth1
children0
last_payout2018-08-01 22:08:45
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length501
author_reputation38,975,615,169,260
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id65,975,264
net_rshares0
@steemitboard ·
Congratulations @pyrolistical! You received a personal award!

<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@pyrolistical/birthday3.png</td><td>Happy Birthday! - You are on the Steem blockchain for 3 years!</td></tr></table>

<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@pyrolistical) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=pyrolistical)_</sub>


###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
properties (22)
authorsteemitboard
permlinksteemitboard-notify-pyrolistical-20190725t205230000z
categoryjavascript
json_metadata{"image":["https://steemitboard.com/img/notify.png"]}
created2019-07-25 20:52:30
last_update2019-07-25 20:52:30
depth1
children0
last_payout2019-08-01 20:52:30
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length636
author_reputation38,975,615,169,260
root_title"How to escape Promise Hell"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id88,742,635
net_rshares0