← Back to list

실제 예제를 사용해서 Async/Await를 마스터하는 방법

이 글은 Adrian Hajdin님이 작성한 How To Master Async/Await With This Real World Example을 번역한 글입니다.

toaonly · 2019-08-28 05:29 · 13 claps · 10.7 min read
#javascript #web-development #coding #programming #tech
Open on Medium ↗
Wiki topics: 💻 · Programming 🌐 · Web Development

실제 예제를 사용해서 Async/Await를 마스터하는 방법

이 글은 Adrian Hajdin 님이 작성한 How To Master Async/Await With This Real World Example 을 참고하여 작성했습니다.

ES7 — Async/Await

ES7 — Async/Await

다뤄볼 컨텐츠:

  1. 소개(callbacks, promises, async/await)
  2. 실제 예제 — 두 개의 API를 호출하여 비동기 데이터를 받아 환율 계산기를 만들어보기

들어가기 전에…

이 글을 작성하신 분께서 유튜브 영상을 제작 하셨습니다.

유튜브를 보면서 코드의 흐름을 쉽게 따라오실 수 있으실 겁니다. 먼저 이 글을 읽고 영상을 보면서 코딩을 해보세요.

영상 주소 : Learn Async/Await in This Real World Project

소개

async/await는 비동기식 코드를 작성하는 새로운 방식입니다. promise 기반으로 만들어졌으며, promise와 동일하게 non blocking입니다.

가장 큰 차이점은 비동기식 코드를 동기식 코드처럼 보이며, 동작한다는 것입니다. 이 부분이 async/await의 가장 큰 특징입니다.

예전에는 비동기식 코드를 작성하려면 callback과 promise를 사용하였습니다.

Callback 동작

setTimeout(() => {
  console.log('This runs after 1000 milliseconds.');
}, 1000);

Callback의 문제점 — 악명 높은 Callback Hell

callback 안에 callback을 감싸고 있다면 다음과 같은 것을 볼 수 있습니다:

Callback Hell

callback이 여러 단계의 깊이를 가진 또 다른 callback에 감싸진 상황은 코드를 유지보수 하고 이해하는 데 있어서 많은 문제점을 만들어 낼 수 있습니다.

Promise 동작

const promiseFunction = new Promise((resolve, reject) => {
  const add = (a, b) => a + b;

  resolve(add(2, 2));
});

promiseFunction.then((response) => {
  console.log(response);
}).catch((error) => {
  console.log(error);
});

promiseFunction 은 해당 함수의 동작을 나타내는 Promise를 반환합니다. resolve 함수는 Promise가 무사히 완료 됐음을 알려줍니다.

promiseFunction 호출 후 .then().catch() 를 호출합니다:

then — promise가 완료 됐을 때 인자로 받은 callback을 실행합니다.

catch — promise에 무언가 문제가 생겼다면 인자로 받은 callback을 실행합니다.

Async 함수

Async 함수는 promise를 사용하여 얻을 수 있는 동일한 결과물을 가져오기 위해 코드를 덜 작성하는 것을 가능케 하는 깨끗하고 간결한 문법을 제공합니다. Async 는 promise의 문법적 설탕에 지나지 않습니다.

Async functions 함수는 함수를 정의하기 전에 function 키워드 앞에 async 라는 키워드를 사용하여 정의합니다:

const asyncFunction = async () => {
  // Code
}

비동기식 함수는 await 를 사용해 일시정지 할 수 있습니다. await 키워드는 async 함수 내부 에서만 사용할 수 있습니다. Await 는 언제나 async 함수를 반환합니다.

다음은 promise와 async/await의 차이입니다:

// Async/Await
const asyncGreeting = async () => 'Greetings';// Promises
const promiseGreeting = () => new Promise(((resolve) => {
  resolve('Greetings');
}));
asyncGreeting().then(result => console.log(result));
promiseGreeting().then(result => console.log(result));

Async/Await 는 동기식 코드처럼 이해하기 쉽습니다.

이제 기초적인 것을 알아봤으니, 실제 예제로 넘어가 봅시다!

Currency Converter

프로젝트에 대한 설명과 설치

이번 튜토리얼에서, 여러분의 Async/Await 에 관한 전반적인 지식 향상을 위해 간단하지만 교육적이고 유용한 어플리케이션을 빌드해볼 예정입니다.

이 프로그램은 변환 하고 싶은 통화 코드와 금액과 변환할 통화코드를 가져옵니다. 나중에, 프로그램은 API로 가져온 데이터에 기반하여 정확한 환율을 보여줄 것입니다.

이번 어플리케이션에서 두 개의 비동기 소스로부터 데이터를 받을 것입니다:

  1. Currency Layer — https://currencylayer.com — 접근 API 키를 사용하기 위해서는 회원가입이 필요합니다. 이 API는 통화별 환율 계산이 필요한 데이터를 제공합니다.
  2. Rest Countries — http://restcountries.eu/ — 이 API는 변환한 통화를 어디에서 사용할 수 있는지에 대한 정보를 제공합니다.

시작하기 전에, 새로운 디렉토리를 만들고 npm init을 실행하세요. 그런 다음 npm i --save axios를 입력하여 axios를 설치합니다. currency-converter.js 파일을 새롭게 생성하세요.

첫 줄에는 const axios = require(‘axios’);를 입력하여 axios를 가져오도록 합니다.

async/await 로 빠져봅시다

우리의 목표는 이번 프로그램에서 세 개의 함수를 만드는 것입니다. 하나도 아니고 두 개도 아닌, 세 개의 비동기 함수를 말이죠.

첫 번째 함수는 통화 데이터를 가져올 것입니다. 두 번째 함수는 국가 데이터를 가져올 것입니다. 그리고 세 번째 함수는 받은 데이터들을 모아 사용자에게 멋지게 출력할 것입니다.

첫 번째 함수 — 통화 데이터를 비동기 방식으로 가져오기

fromCurrency 와 toCurrency를 인자로 갖는 비동기 함수를 만듭니다.

const getExchangeRate = async (fromCurrency, toCurrency) => {}

이제부터 데이터를 가져와야 합니다. async/await를 사용하여 변수에 데이터를 할당 할 수 있습니다.

회원가입 후 받아온 접근키(yourAccessKey)를 입력해야 합니다.

const getExchangeRate = async (fromCurrency, toCurrency) => {
  const response = await axios.get('http://www.apilayer.net/api/live?access_key=[yourAccessKey]')
}

응답값으로 받아온 데이터는 바로 아랫줄에 놓을 수 있습니다.

const rate = response.data.rates;

기준 환율을 유로로 합니다. euro 라는 변수를 만들고 1 / currency 라는 값을 넣어줍니다.

const euro = 1 / rate[`USD${fromCurrency}`];

마지막으로 환율 알기 위해 euro에 통화를 값을 곱합니다:

const exchangeRate = euro * rate[`USD${toCurrency}`];

최종적으로 이러한 내용의 함수가 됩니다:

두 번째 함수 — 국가 데이터를 비동기 방식으로 가져오기

currencyCode 를 인자로 받는 비동기 함수를 만듭니다:

const getCountries = async (currencyCode) => {}

앞에서 본 것 처럼 데이터를 받아와 할당합니다:

const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);

데이터를 매핑하고 각각의 country.name을 반환합니다:

return response.data.map(country => country.name);

최종적으로 이러한 내용의 함수가 됩니다:

마지막 함수 — 지금까지 한 것들을 합쳐보자

fromCurrency, toCurrency, amount 를 인자로 받는 비동기 함수를 만듭니다:

const convertCurrency = async (fromCurrency, toCurrency, amount) => {}

먼저 통화 데이터를 가져옵니다:

const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);

두 번째로 국가 데이터를 가져옵니다:

const countries = await getCountries(toCurrency);

세 번째로 amount를 변환합니다:

const convertedAmount = (amount * exchangeRate).toFixed(2);

마지막으로 사용자에게 변환된 정보를 보여줍니다:

return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`;

위의 과정들을 모두 마치면 다음과 같이 보입니다:

에러 케이스를 처리하기 위해 try/catch를 넣어보자

지금 까지 짠 로직을 try 로 감싸야 합니다. 그리고 에러가 발생한다면 잡아야(catch) 합니다:

const getExchangeRate = async (fromCurrency, toCurrency) => {
  try {
    const response = await axios.get('http://www.apilayer.net/api/live?access_key=e9899738119bfeb79703c0b75c18eecc')
    const rate = response.data.quotes
    const euro = 1 / rate[`USD${fromCurrency}`]
    const exchangeRate = euro * rate[`USD${toCurrency}`]

    return exchangeRate
  } catch(error) {
    console.log(error)
    throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`)
  }
}

두 번째 함수도 동일하게 해주세요:

const getCountries = async (currencyCode) => {
  try {
    const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`)

    return response.data.map(country => country.name)
  } catch (error) {
    throw new Error(`Unable to get countries that use ${currencyCode}`)
  }
}

세 번째 함수는 첫 번째 함수와 두 번째 함수를 가져와서 사용하기 때문에 별도로 에러를 확인할 필요는 없습니다.

드디어 함수를 호출하고 데이터를 받을 수 있게 됬습니다:

convertCurrency('USD', 'KRW', 20)
  .then((message) => {
    console.log(message)
  })
  .catch((error) => {
    console.log(error.message)
  })

다음과 같은 결과 값을 받아볼 수 있습니다:

후기

저의 첫 Medium 포스트입니다. 첫 포스트를 다른 분이 작성한 것을 기반으로 할 줄을 몰랐습니다 ㅎㅎ

중간 중간 해석이 어색한 부분(아주 많을 것 같아요)과 이해가 안 되시는 부분이 있으시면 코멘트로 남겨주세요.

감사합니다 :)


메타데이터
post_id
d70e67d8a968
slug
실제-예제를-사용해서-async-await를-마스터하는-방법-d70e67d8a968
url
https://medium.com/@toaonly/%EC%8B%A4%EC%A0%9C-%EC%98%88%EC%A0%9C%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%84%9C-async-await%EB%A5%BC-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-d70e67d8a968
canonical_url
https://medium.com/@toaonly/%EC%8B%A4%EC%A0%9C-%EC%98%88%EC%A0%9C%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%84%9C-async-await%EB%A5%BC-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-d70e67d8a968
author_url
https://medium.com/@toaonly
status
ok
fetched_at
2026-07-29 13:30:38