async & await (Promise) JavaScript
저번 포스트에서는 Promise에 대해서 정리하였는데 이 개념을 더 쉽게 사용하도록 도와주는 async, await 문법에 대해 정리
해보려고 합니다. 비동기 처리를 활용하기 위해 3개의 글을 포스팅하였는데 이번이 마지막 시리즈입니다.
이전 포스트 링크도 남겨 놓겠습니다.
[JavaScript] - Promise(then & catch) - JavaScript
async & await
이 문법들을 이용해 비동기적인 코드들을 동기적 처리 코드처럼 작성할 수 있게 됩니다. 쉽게 말하자면 더 간결하게 작성이 가능합니다. 이를 syntactic sugar라고도 부릅니다 그럼 각 기능을 확인해보겠습니다.
async
async와 await는 항상 같이 사용하여야 에러가 발생하지 않기 때문에 나눠서 설명하는 것이 의미가 크진 않으나 따로 설명하자면 기존에는 Producer를 이용하여 Promise를 생성하면 resolve의 경우와 reject의 경우를 정리해야 하는 불편함이 있었습니다. 또한 then과 catch를 사용하여 chaining 해주어야 정상적으로 작동했습니다.
기존 방식
function fetchUser() {
return new Promise((resolve, reject) => {
resolve('mxx')
})
}
const user = fetchUser();
user.then(console.log); // 'mxx' 출력
console.log(user)
이와 같은 결과를 얻을 수 있었습니다. 하지만 async를 사용하면 new Promise를 작성하지 않아도 됩니다. 즉 async 작성하면 return 값을 promise 객체로 반환합니다.
async 사용
async function fetchUser() {
return 'mxx';
}
const user = fetchUser();
user.then(console.log); // 'mxx' 출력
console.log(user)
코드에서 확인할 수 있듯이 async 문법을 통해 훨씬 간결한 코드 작성이 가능해집니다.
await
await 어떠한 명령이 완료될 때까지 기다렸다가 리턴 값을 반환, 즉 비동기적 처리를 동기적 처리처럼 보이도록 합니다.
async & await를 사용하지 않은 방식
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function getApple() {
return delay(1000)
.then(() => '🍎');
}
function getBanana() {
return delay(1000)
.then(() => '🍌');
}
function pickFruits() {
return getApple().then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`);
});
}
pickFruits().then(console.log); // 🍎 + 🍌 출력
지금은 간단해보이지만 더 깊어진다면 콜백 지옥을 경험하게 됩니다. 이를 async와 await를 활용하여 더 간단하게 작성해보면...
async & await 사용
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000);
return '🍎';
}
async function getBanana() {
await delay(1000);
return '🍌';
}
async function pickFruit() {
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
pickFruits().then(console.log);
위의 코드와 똑같은 결괏값 🍎 + 🍌를 출력하지만 코드가 직관적으로 변한 것을 확인할 수 있습니다.
async와 await 문법의 에러 처리는 어떻게해야할까요?
async & await 예외 처리
async function pickFruit() {
try {
const apple = await getApple();
const banana = await getBanana();
} catch() {
return new Error('error');
}
return `${apple} + ${banana}`;
}
이런 식으로 try안의 코드를 실행해보고 실패하면 catch안의 코드를 실행하게 코드를 작성하면 됩니다.
하지만 이러한 방식은 getApple과 getBanana 모두 가져오는 동안 총 2초를 기다려야 합니다. 만약 병렬적인 처리를 원한다면 아래와 같은 방식으로 pickFruits를 작성하면 됩니다.
병렬 처리 방식
async function pickFruit() {
const applePromise = getApple();
const bananaPromise = getBanana();
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
이러한 방식을 이용하면 1초 뒤에 🍎 + 🍌을 출력합니다.
이 방식 외에도 promise의 API를 이용하면 되는데 사용법은 아래와 같습니다.
Promise API
Promise.all을 이용한 병렬 처리 방식
function pickAllFruits() {
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join(` + `));
}
pickAllFruits().then(console.log);
Promise.all이라는 API를 사용해 배열 안에 실행할 함수들을 적고 각 요소들이 병렬적으로 받아져 출력할 때에는 각 배열을 출력하듯이 출력해주면 됩니다.
이외에도 유용한 API는 race가 있습니다. race는 더 빨리 받아진 값을 리턴하는 기능을 합니다.
Promise.race 사용
function pickFastOne() {
return Promise.race([getApple(), getBanana()]);
}
pickFastOne().then(console.log);
만약 사과가 1초 바나나가 2초 걸린다면 사과를 출력해줍니다.
이 포스팅을 마지막으로 비동기적 처리에 대해 더 깊게 생각해볼 수 있었습니다. 서버와 통신하는 과정에서 필연적인 처리 방식이기에 조금 더 자세하게 정리하게 되었고 이 정리를 통해 더 좋은 개발자로 성장할 수 있으면 좋겠습니다.
'JavaScript' 카테고리의 다른 글
Promise(then & catch) - JavaScript (0) | 2022.04.14 |
---|---|
동기적, 비동기적 처리, 콜백 함수 - JavaScript (0) | 2022.04.13 |
쿠키, 로컬스토리지와 세션스토리지 - JavaScript (0) | 2022.04.04 |
Webpack과 Babel - JavaScript (0) | 2022.03.30 |
클래스(Class) - JavaScript (0) | 2022.02.28 |