JS: Using Async (with Promises)

##TLDR here's an async/await code template

const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('I did something'), 3000) }) } const doSomethingElseAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('I did something too'), 5000) }) } const doSomething = async () => { const result = await doSomethingAsync() console.log(result) } const doManyThings = async () => {
const results = await Promise.all([doSomethingAsync, doSomethingElseAsync])
.then(res => return res)
.catch(err => console.log('error')) } console.log('Before') doSomething() // run one async function doManyThings() // run multiple async functions console.log('After')

##What are all these Promises doing in my async/await code?

This article assumes that you have used async/await in Javascript before, but have been doing so by doggedly following 'learn X in 5 minutes' (like me) and are still a bit hazy on the fundamentals.

###Time to get to the bottom of Async/Await.

ever wondered why you needed to type

const someFunction = () =>
  new Promise(resolve => /*do something and then..*/ resolve('result'))

even if you're using async/await?

What about having to use

const result = Promise.all([someFunction, someOtherFunction])
.then(result => /*do stuff with results*/)
.catch(error => /*log the error*/)

to collect your multiple async functions (because why would you write async code and then not run multiple functions asynchronously?)

well, async/await is syntactic sugar. more precisely, it is syntactic sugar for Promise chaining. You still have to create async functions with new Promise(), as well as collect your promises with Promise.all() or Promise.race()

also,

Prepending the async keyword to any function means that the function will return a promise.

and also,

Debugging promises is hard because the debugger will not step over asynchronous code. Async/await makes this very easy because to the compiler it’s just like synchronous code.

he also has a really good comparison:

For example here’s how you would get a JSON resource, and parse it, using promises:

###Promises

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => response.json()) // parse JSON
}
getFirstUserData()

###Async/Await

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await user.json() // parse JSON
  return userData
}
getFirstUserData()

####Promise chaining my async from taniarascia

// First promise returns an array
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(
      () => resolve([{ id: 'jon' }, { id: 'andrey' }, { id: 'tania' }]),
      600
    )
  })
}

// Second promise relies on the resulting array of first promise
const getIdFromUser = users => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(users.id), 500)
  })
}

// Third promise relies on the result of the second promise
const capitalizeIds = id => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

const runAsyncFunctions = async () => {
  const users = await getUsers()

  Promise.all(
    users.map(async user => {
      const userId = await getIdFromUser(user)
      console.log(userId)

      const capitalizedId = await capitalizeIds(userId)
      console.log(capitalizedId)
    })
  )

  console.log(users)
}

runAsyncFunctions()

##other async/await things multiple async functions in series

how to Promise.all() properly

##reference from 'The React Handbook' medium article

Async/Await

Promises