theonlychase
10/8/2018 - 11:12 PM

callbacks, promises, async/await

1. Callbacks
    - The function you're passing as an argument is called a callback. 
    - The function you're passing the callback function to is called a "higher order function".
    - Delay execution of a function until a particular time
    function add (x, y) {
        return x + y
    }
    function addFive (x, addReference) {
        return addReference(x, 5) // 15 - Press the button, run the machine.
    }
    addFive(10, add) // 15

    - We can also delay a function "until we have the data we need as well".
    const id = 'tylermcginnis'

    $.getJSON({
        url: `https://api.github.com/users/${id}`,
        success: updateUI,
        error: showError,
    })
    // Call updateUI if the data comes back successfully, or call showError if not. 

    - avoid callback hell obviously
    - inversion of control

2. Promises
    - Giving your number to a restaurant is just like giving a callback function to a third party service. 
    - you expect the restaurant to text you when a table opens up, just like you expect a third aprty service to invoke your function when and how they said they would. 
    - Once your number or callback function is in their hands thouigh, you've lost all control. (inversion of control)

    - Promises, by design, allow you to keep all of the control. 
    - expand the above example - instead of giving your number to the restaurant, they give you a buzzer instead. 
        - you can do whatever you like as you're waiting for the table to open up, but now you don't have to give up anything. 
        - they have to give YOU something. There is no inversion of control. 
    - The buzzer will always be in 1 of three states:
        1. pending
            - default, initial state. When they give you the buzzer, it's in this state. 
        2- fulfilled 
            - state the buzzer is in when it's flashing and your table is ready
        3. rejected
            - state the buzzer is in when something goes wrong. 

    - Promises exist to make the complexity of async requests more manageable. 
    1. Create a promise
    const promise = new Promise();
    2. How do you change the status of a Promise?
        - the Promise constructor takes in a single argument, a callback function. This cb takes in two arguments, resolve and reject. 
            - resolve - function that allows you to change status of the promise to fulfilled. 
            - reject - function that allows you to change the status of promise to rejected. 
                - used to send back values to the promise object
    3. How do you listen for when the status of a promise changes?
        - When you create a mew Promise, you're really creating a plain old JS object. 
            - This object can invoke two methods, then and catch. 
                - .then accepts two callbacks
                    - the first is invoked when the promise is resolved. gives you the resolved value
                    - the second is invoked when the promise is rejected. 
            - You pass the function you want to run if the async function is successful to then(), and if the async function fails to catch()


1. Async/Await
    - async functions return a promise
        - amytime you add async to a function, that function is going to implicitly return a promise
            async function getPromsise() {}
            const promise = getPromise();
        - Even though getPromise is empty, it still returns a promise since it is an async function
        - if the async function returns a value, that value will also get wrapped in a promise. That means you'll have to use .then() to access it
            async function add(x, y) {
                return x + y;
            }
            add(2,3).then(result => {
                console.log(result);
            });
    - await without async is bad
        - if you try to use await inside a function that isn't async, you'' get an error

    - Error Handling
        - most common approach is to wrap your code in a try/catch block to catch the error
        $("#btn").on("click", async () => {
            try {
                const user = await getUser('tylermcginnis')
                const weather = await getWeather(user.location)

                updateUI({
                user,
                weather,
                })
            } catch (e) {
                showError(e)
            }
        })