본문 바로가기
Javascript

[javascript] async & await

by 홍두두현 2023. 1. 16.
반응형
신발이 당첨되고 싶었는데 앱 포인트가 당첨됐다. 느슨해진 일상 속에 긴장감을 준...

async await

promise를 좀 더 간결하고 간편하게 동기적으로 실행되는 것처럼 보이게 만들어주는 기능이다.
기존에 promise.then.then.then..... 이렇게 계속 체이닝을 하는 것보다 api로 좀 더 간결하게 async await을 사용하면 동기식으로 코드를 순서대로 작성하는 것처럼 작성할 수 있게 도와준다.

예제 1.

먼저 간단한 기능적인 예시로 이름을 가져오는 함수가 있다고 가정하고 기존에 Promise 작업하는 것과 동일하게 작업을 하면 이렇게 나온다.

function fetchUser() {
    return new Promise((resolve, reject)=>{        
        resolve('DuHyeon');
    })
}

하지만 이때 function 앞에 async를 붙여주게 된다면 그 코드블록은 자동으로 Promise로 바뀌게 된다.

async function fetchUser() {
    return ('DuHyeon');
}

다른 예제를 해보려 하는데 먼저 네트워크 통신을 해서 백엔드에서 데이터를 받아오는데 10초 걸리는 코드가 있다고 가정해 보자 10초가 걸리는 코드 후에 그다음에 작성된 코드들이 실행되므로 화면엔 10초 전에 아무것도 나오지 않을 것이다. 그래서 비동기적으로 실행할 수 있게 해줘야 한다.

예제 2.

사과와 바나나를 각각 시간에 맞게 가져오는 함수를 작성해 보겠다.

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve,ms));
}

async function getApple () {
    await delay(2000);
    return '🍎';
}

async function getBanana () {
    await delay(1000);
    return '🍌';
}

먼저 delay()으로 몇 초 후에 실행될 건지 시간초를 받아서 그 시간 후에 뿌려주는 함수를 만들어 놓고 위에서 작성한 async를 통해 함수를 작성한다.
여기서 await은 함수명 앞에 async가 붙은 함수에서만 쓸 수 있다.

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

pickFruits().then(console.log)
// 🍎 + 🍌

하지만 개수가 2개가 아니라 더 많아지게 된다면 아무리 콜백지옥을 탈출하려 Promise를 사용했지만 코드가 난잡해질 수도 있다.
좀 더 간결하게 사용할 수 있는 다른 방법으로 작성해 보자.

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve,ms));
}

async function getApple () {
    await delay(2000);
    return '🍎';
}

async function getBanana () {
    await delay(1000);
    return '🍌';
}

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

pickFruits().then(console.log)
// 🍎 + 🍌

이렇게. then대신 apple과 banana를 async await으로 다 받아와서 return 하면 좀 더 간결하게 작성이 가능하다. 하지만 사과를 받는데 3초 바나나를 받는데 3초, 이렇게 순차적으로 진행하면 총 6초를 기다려야 하며 비효율적이다. 서로 연관이 되어있지 않기 때문에 기다릴 필요가 있지 않다.
이를 개선하려면 apple과 banana를 병렬적인 상태로 두어야 한다.

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

pickFruits().then(console.log);
// 🍎 + 🍌

지금의 코드를 실행하면 6초가 아닌 3초 만에 값이 나온다.
병렬적인 상태로 두려면 applePromise,bananaPromise처럼 바로 만들어 준다면 Promise안에 있는 코드블록이 바로 실행이 된다.

하지만 이렇게 병렬적으로 기능을 수행해야 한다면 다른 더 좋은 작성 방법이 있다.

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

pickFruits().then(console.log);
// 🍎 + 🍌

all()이라는 api인데 all()은 promise 배열을 전달하게 되면 모든 promise가 전부 받을 때까지 모아주는 api이다. 그렇게 되면 fruits로 전달받은 걸 join으로 합쳐준다면 원래 구하고자 했던 값인 🍎 + 🍌이 나오게 된다.

REFERENCE

드림코딩 by 엘리 : https://www.youtube.com/watch?v=JB_yU6Oe2eE&t=1452s

반응형

'Javascript' 카테고리의 다른 글

[javascript] 최소 ~ 최대값 랜덤 수 뽑기  (0) 2023.01.16
[web]semantic web / semantic tags  (0) 2023.01.16
[javascript] Promise  (0) 2023.01.16
[javascript] 비동기 처리  (0) 2023.01.16
[javascript] spread  (0) 2023.01.16

댓글