# Promise

Given each of these operations is done one after the other, you can use Promises. If you know how Promises work, feel free to skip to [Promise Composition](#Promise Composition) below. Below is a quick recap on returning values in Promises vs. Promise.resolve and making them with less code.

# Promise Return Value Recap

Promises have the nice feature in their then statement, you can return a value, not just a Promise. Normally you’ll see people return a Promise:

const twoThings = () =>
    Promise.resolve(1)
    .then(result => Promise.resolve(result + 1))

To try it out:

twoThings()
.then(result => log("result:", result) // 2

However, once you’re in a Promise chain, as long as it’s not an Error, you can return whatever you want and it’ll resolve into the next then. Rewriting the same function above using that would be:

const twoThingsv2 = () =>
    Promise.resolve(1)
    .then(result => result + 1)

To try v2 out:

twoThings()
.then(result => log("result:", result) // 2

Or just defining the intermediate function separately. Here's a simple function to add 1:

const add1 = result =>
    result + 1

We can then just put it in the then and it'll get called with whatever the value is from the previous Promise:

const twoThings = () =>
    Promise.resolve(1)
    .then(add1)

# Promise Composition

Using a Promise, we can take our nested function:

const parse1 = str =>
    startCaseNames(formatNames(filterHumans(parsePeople(str))))

And convert it to a more readable Promise version, even though it’s synchronous code:

const parse3 = str =>
    Promise.resolve(str)
        .then(parsePeople)
        .then(filterHumans)
        .then(formatNames)
        .then(startCaseNames)

The downside is it still has to be called like a normal asynchronous Promise:

parse3(peopleString)
.then(log) // ["Jesse Warden", "Brandy Fortune"]

However, it does have the advantage of being a bit easier to read, easier to follow in terms of what is happening when and in what order. Additionally, Promises have built-in try/catch so the error handling is in one place. For functions that have Error's like parsePeople which could get a bad input, it composes nicely into Promises.

# Debugging

Finally, because of the chaining, like the Composition example, you can quickly comment out a section of the chain to debug what’s going up to a certain point:

const parse3 = str =>
    Promise.resolve(str)
        .then(parsePeople)
        .then(filterHumans)
        //.then(formatNames)
        //.then(startCaseNames)

You can also do a tap function like we did in Composition to determine how things are progressing up to a certain point as well. For now, we’ll use a modified log function to take a value, log it out, then return whatever you were passed:

const tap = (...args) => {
    log(args)
    return Promise.resolve.apply(Promise, args)
}

Notice below, we can use tap to log things out, or use log manually if we want more detail:

const parse3 = str =>
    Promise.resolve(str)
        .then(tap)
        .then(parsePeople)
        .then(tap)
        .then(filterHumans)
        .then(humans => log("humans:", humans) || humans)
        .then(formatNames)
        .then(tap)
        .then(startCaseNames)
        .then(final => log("final is:", final))