실제 예제를 사용해서 Async/Await를 마스터하는 방법
이 글은 Adrian Hajdin님이 작성한 How To Master Async/Await With This Real World Example을 번역한 글입니다.
실제 예제를 사용해서 Async/Await를 마스터하는 방법
이 글은 Adrian Hajdin 님이 작성한 How To Master Async/Await With This Real World Example 을 참고하여 작성했습니다.

ES7 — Async/Await
다뤄볼 컨텐츠:
- 소개(
callbacks,promises,async/await) - 실제 예제 — 두 개의 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로 가져온 데이터에 기반하여 정확한 환율을 보여줄 것입니다.
이번 어플리케이션에서 두 개의 비동기 소스로부터 데이터를 받을 것입니다:
- Currency Layer — https://currencylayer.com — 접근 API 키를 사용하기 위해서는 회원가입이 필요합니다. 이 API는 통화별 환율 계산이 필요한 데이터를 제공합니다.
- 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