Search code examples
javascriptes6-promise

Why Use JS Promises Instead of IF/ELSE / Ternary?


I'm doing some reading up on JS Promises to up-skill.

Here's my quandry: Say you want to console.log('we done, bruh!') AFTER your data's come back.

so with a Promise, you might say:

let iWantToLogOut = function() {

    let data = fetch('https://jsonplaceholder.typicode.com/users')

    return new Promise((resolve) => {
        resolve(data)
    })
}

And then resolve that promise like:

iWantToLogOut().then((dataBack) 
=> databack.json())
 .then((json) => {
   console.log('We done, bruh! Look: ', json)         
 })

So that's great. You get your API data back and then we log our msg out.

But isn't it just way easier to go:

   let data = fetch('https://jsonplaceholder.typicode.com/users');
   data ? console.log('we done, bruh!') : null;

I'm probably over-simplifying/missing something (because... well... i'm retarded) but I just want to make sure i'm really understanding Promises first before i move onto Async/Await.


Solution

  • But isn't it just way easier to go:

    let data = fetch('https://jsonplaceholder.typicode.com/users');
    data ? console.log('we done, bruh!') : null;
    

    It would be, but it doesn't work. What fetch returns is a promise, not the result of the operation. You can't return the result of an asynchronous process. More: How do I return the response from an asynchronous call?

    In the upcoming ES2017 spec, though, we have syntactic sugar around promise consumption which will let you write this:

    let data = await fetch('https://jsonplaceholder.typicode.com/users');
    // --------^^^^^
    console.log('we done, bruh!');
    

    Note we don't even need the conditional, because await converts a promise rejection into an exception.

    That code would need to be in an async function, e.g.:

    (async function() {
        let data = await fetch(/*...*/);
        // use data here
    })();
    

    The JavaScript engines in some browsers already support async/await, but to use it in the wild, you'll want to transpile with Babel or similar.


    Note: You've shown

    so with a Promise, you might say:

    let iWantToLogOut = function() {
    
        let data = fetch('https://jsonplaceholder.typicode.com/users')
    
        return new Promise((resolve) => {
            resolve(data)
        })
    }
    

    There are a couple of problems with that code:

    1. It never settles the promise you created if the fetch fails.

    2. It calls something data which is not data, it's a promise of data (that's mostly style, but it's misleading).

    3. It exhibits the promise creation anti-pattern. You already have a promise (from fetch), no need to create another.

    iWantToLogOut should be simply:

    let iWantToLogOut = function() {
        return fetch('https://jsonplaceholder.typicode.com/users');
    };
    

    That returns a promise that will be resolved with the data, or of course rejected. Which you'd then consume with promise methods or await (within an async function).