자바스크립트에서 비동기처리를 다룰 수 있는 방법에는 여러가지가 있지만 주로 이전
Event Loop에서 비동기처리 방식으로 다뤘던 callback, 이 외에도 Promise , async/await 를 활용한다.
그 중 오늘은 Promise와 async/await 에 대하여 알아볼 것이다.
우리는 Promise가 등장하기 이전에, 비동기 작업을 처리할 때 콜백 함수를 사용했었다.
그러면 왜 계속 콜백 함수를 사용하지 않고 Promise가 나타나게 되었을까? 그건 바로 콜백 지옥(Callback Hell) 때문이다.

초기의 자바스크립트는 코드의 복잡도가 높지 않아서 콜백 함수를 중첩하는 일이 드물었지만, 현재는 규모가 커졌기 때문에 위 사진처럼 비동기 작업이 많아질 수록 콜백 함수의 중첩이 깊게 들어가게 되는 것이다. 이것을 바로 콜백 지옥이라고 한다.
이를 보완하기 위해 ES6에서 추가된 개념이 바로 Promise인 것이다.
const state = true;
const promise = new Promise((resolve, reject) => {
if (state) {
resolve('result');
} else {
reject('rejected reason');
}
});
// promise 후속처리 메서드
promise
.then((res) => {
console.log(res);
})
.catch((error) => {
console.error(error);
});
Promise는 위와 같이 new 연산자와 함께 호출하여 생성한다.
이때, 비동기 처리를 수행할 콜백 함수를 인수로 전달받게 되는데, 이 콜백 함수는 resolve와 reject 함수를 인수로 전달받는다. 여기서 비동기 처리가 성공하게 되면 resolve 함수를 호출하고, 실패하면 reject 함수를 호출하게 되는 것이다.
| Promise 상태 | 의미 | 상태 변경 조건 |
|---|---|---|
| pending | 비동기 처리가 아직 완료되지 않은 상태(대기) | 프로미스가 생성된 직후 기본 상태 |
| fulfilled | 비동기 처리가 완료된 상태(성공) | resolve 함수 호출 |
| rejected | 비동기 처리가 완료된 상태(실패) | reject 함수 호출 |
이 때 Promise의 후속 처리 메서드로 then,catch를 활용할 수 있다.
resolve 반환 값에 대해서는 then() 을 통해 결과 값을 반환 받을 수 있고 reject 의 반환 값에 대해서는 catch() 를 통해 반환 받는다.
하지만 Promise에서 상황에 따라 then()이 많아질 경우 콜백지옥과 같은 상황(=꼬리에 꼬리를 무는 코드)이 일어나기 때문에 이를 보완하기 위해 async / await가 나오게 된 것이다.
async / await에서는 await 를 통해 Promise 반환 값을 받아 올 수 있다.
async는 함수의 앞에 붙여서 해당 함수가 비동기 함수임을 나타내며, await는 비동기 함수의 실행 결과를 기다리는 키워드이다.
하지만 async/await 를 사용하기 위해서는 선행되어야 하는 조건이 있는데,
await 는 async 함수 안에서만 동작한다는 것이다.
const getData = async() =>{
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
console.error(error);
}
}
await 키워드는 Promise 객체가 완료될 때까지 코드 실행을 일시 중지하므로,
try-catch 블록 안에서 사용하여 에러 처리를 할 수 있다.
fetch에서 네트워크 에러가 발생할 경우, await 이후의 코드는 실행되지 않으며,
catch 블록으로 제어가 넘어가 에러를 처리할 수 있다.
에러 핸들링
-> Promise 활용 시 then-catch를 통해 에러 핸들링이 가능하지만,
async/await는 에러 핸들링 기능이 따로 없어 try-catch를 활용해야한다.
코드 가독성
-> 코드가 길어지면 길어질수록, Promise의 .then() 지옥의 가능성으로 인해
async/await 를 활용한 코드가 가독성이 좋다.