javascript - async, await

김동하·2020년 9월 27일
0

javascript

목록 보기
32/58

async와 await은 promise를 간결하고 동기적으로 실행되는 것처럼 만들어준다.

async

function fetchUser(){

  // do network request in 10 secs
  return "dongha"
}

const user = fetchUser();

유저의 데이터르 받아오는 fetchUser라는 함수가 있고 10초가 걸린다. user라는 변수에 리턴값을 할당할 때 동기적 실행은 10초가 걸린다.(그동안 자바스크립트 엔진은 다른 일을 안 한다)

이것을 promise로 바꾸면

function fetchUser(){

  // do network request in 10 secs
  return new Promise((resolve, reject))
}

const user = fetchUser();

promise 안에는 resolve와 reject란 콜백 함수를 받는 콜백함수를 만든다.

function fetchUser(){
  // do network request in 10 secs
  return new Promise((resolve, reject) =>{
    resolve("dongha")
  })
}

const user = fetchUser();
user.then(console.log) // dongha

user 변수는 리턴값을 받으니까 then이란 콜백 함수를 이용해서 콘솔에 찍어주면 dongha가 출력된다.

async

async function fetchUser(){
  // do network request in 10 secs
return "dongha"
}

const user = fetchUser();
user.then(console.log) // dongha

function 앞에 async 를 적어두면 promise를 한 것과 똑같은 효과다!

await

await은 async가 붙은 함수 안에서만 사용 가능하다.

function delay(ms){
  return new Promise(resolve => setTimeout(resolve, ms))
}
async function getApple(){
  await delay(3000)
  return "apple"
}

async function getBanana(){
  await delay(3000)
  return "banana"
}

delay 함수는 promise를 리턴하는데 ms를 파라메터로 받아서 ms가 지나면 resolve를 호출한다. await은 3초가 끝날 때가지 기다려준다. 즉, 3초가 지나고 "apple"을 리턴하는 프로미스가 만들어진다.

function getBanana(){
  return delay(3000)
   .then(()=>"banana")
}

getBanana 함수를 promise를 쓰는 함수로 만들면 위와 같다. await을 쓰는 것이 동기적으로 보여 직관적이다.

apple과 banana 를 가져오는 pickFruits 함수를 만든다고 가정하자.

function pickFruits() {
    return getApple()
        .then(apple => {
            return getBanana()
                .then(banana => `${apple} + ${banana}`)
        })
}

pickFruits().then(console.log) // apple + banana

promise도 중첩하면 콜백지옥과 유사해진다. async 를 사용하면

async function pickFruits(){
  const apple = await getApple()
  const banana = await getBanana()

  return `${apple} + ${banana}`
 
}

pickFruits().then(console.log) // apple + banana

async를 함수 앞에 붙이고 await 을 사용하면 훨씬 간결해진다.

에러 발생

function getBanana(){
  return delay(3000)
   throw "error"
   return "apple"
}

async function pickFruits(){

  try {
    const apple = await getApple()
    const banana = await getBanana()
  } 
  catch() {}
  
  return `${apple} + ${banana}`
}

pickFruits().then(console.log) //  apple + banana

try와 catch로 에러를 핸들링 가능하다!

await의 병렬 처리

getApple 함수가 3초 딜레이가 되고 getApple 함수가 3초 딜레이 되고 실행된다. 즉, 6초가 직렬적으로 처리되니까 비효율적인데(무슨 말인지 이해가 완전히 되지 않는다!) 바나나와 사과를 받는 것은 연관이 되지 않았기 때문에 기다릴 필요가 없다 동시 진행을 해도 된다는 뜻!


async function pickFruits() {
 const applePromise = getApple()
 const bananaPromise = getBanana()
 
 const apple = await applePromise
 const banana = await bananaPromise
    
 return `${apple} + ${banana}`
}

pickFruits().then(console.log) // apple + banana

applePromise와 bananaPromise 란 변수를 만들어 getApple()을 할당해준다. 즉, promise를 바로 실행한다. 그리고 await으로 apple변수와 동기화를 시켜주면 두 함수가 병렬적으로 실행되어 3초만에 완료!

위의 경우 간결하게 작성이 가능하다.

function pickAllFruits() {
    return Promise.all([getApple(), getBanana()]).then(fruits => fruits.join(' + '))
}
pickAllFruits().then(console.log) // apple + banana apple + banana

all이란 api는 promise 배열을 전달하면 모든 promise들이 병렬적으로 다 받을 때까지 기다린다.

function pickOnlyOne(){
  return Promise.race([getApple(), getBanana()] )
}
pickOnlyOne().then(console.log) // apple

race는 배열 형태로 들어온 promise 중 아무 것이나 가장 먼저 받는 것을 전달한다.

출처 : https://www.youtube.com/watch?v=aoQSOZfz3vQ&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=13

profile
프론트엔드 개발

0개의 댓글