
오늘은 자바스크립트의 async와 await에 대해 공부하면서 정리한 내용을 공유해보려고 한다. 자바스크립트에서 비동기 처리를 할 때 자주 겪는 콜백 지옥(callback hell)을 해결하고, 코드를 더 명확하게 작성할 수 있는 방법이다.
자바스크립트는 한 번에 하나의 작업만 처리할 수 있는 싱글 스레드 언어이다. 만약 네트워크 요청이나 파일 읽기처럼 시간이 오래 걸리는 작업을 기다리고 있으면 다른 작업을 할 수 없다. 그래서 이런 작업을 기다리지 않고 다른 작업을 계속 진행할 수 있도록 비동기 처리를 사용한다.
예전에는 setTimeout, XMLHttpRequest(XHR), Promise 등을 써서 비동기 작업을 처리했는데, 최근에는 async와 await을 사용하면 마치 동기적인 코드처럼 더 간결하고 이해하기 쉽게 작성할 수 있어서 좋았다.
async를 함수 앞에 붙이면 그 함수는 항상 Promise를 반환한다.
async function sayHello() {
return "Hello, Async!";
}
sayHello().then(console.log); // "Hello, Async!"
이렇게 쓰면 자동으로 Promise.resolve("Hello, Async!") 형태로 반환된다.
await는 반드시 async 함수 내부에서만 사용할 수 있고, 비동기 작업(Promise)의 결과가 나올 때까지 기다리게 해준다.
async function fetchMessage() {
let response = await new Promise(resolve => setTimeout(() => resolve("비동기 작업 완료!"), 2000));
console.log(response);
}
fetchMessage();
// 2초 후 "비동기 작업 완료!" 출력
이렇게 하면 코드 흐름이 중간에 멈추는 것처럼 보이지만, 실제로는 비동기로 처리되고 있다.
async/await를 사용하면 다음과 같은 장점이 있다.
기존의 Promise 방식은 .then()이 연달아 붙어서 코드를 복잡하게 만든다.
fetch("https://jsonplaceholder.typicode.com/users/1")
.then(res => res.json())
.then(user => fetch(`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`))
.then(res => res.json())
.then(posts => console.log(posts))
.catch(err => console.error(err));
async function fetchUserAndPosts() {
try {
let userResponse = await fetch("https://jsonplaceholder.typicode.com/users/1");
let user = await userResponse.json();
let postsResponse = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`);
let posts = await postsResponse.json();
console.log(posts);
} catch (error) {
console.error("에러 발생:", error);
}
}
fetchUserAndPosts();
코드가 위에서 아래로 순서대로 흘러가서 읽기 쉽다.
async/await는 일반적인 try...catch 방식으로 에러 처리가 가능해서, 어디서 에러가 발생했는지 쉽게 확인할 수 있다.
async/await로 작성된 코드는 일반 동기 코드처럼 디버깅이 간단해진다. Promise 방식에 비해 문제의 원인을 빠르게 찾을 수 있다.
비동기 작업이 여러 개라면 Promise.all()을 사용해서 병렬로 처리할 수 있다. 한 번에 여러 요청을 보내고, 더 빠르게 결과를 받을 수 있다.
async function fetchMultipleData() {
let [user, posts] = await Promise.all([
fetch("https://jsonplaceholder.typicode.com/users/1").then(res => res.json()),
fetch("https://jsonplaceholder.typicode.com/posts?userId=1").then(res => res.json())
]);
console.log("사용자:", user);
console.log("게시물:", posts);
}
fetchMultipleData();
await은 반드시 async 함수 내부에서만 사용할 수 있다.Promise.all()을 활용해서 병렬 처리를 해야 한다.성능상 두 방식에 큰 차이는 없다. 하지만 async/await이 가독성과 유지보수 측면에서 더 유리하므로, 코드가 복잡해질 때는 적극적으로 사용하는 것이 좋다.
async: 비동기 함수로 만들어 항상 Promise를 반환한다.await: 비동기 작업의 완료를 기다린다.try...catch: 에러 처리가 쉽다.Promise.all(): 여러 작업을 동시에 처리할 수 있다.콜백 지옥을 해결함과 동시에 더 명확하고 유지보수하기 쉬운 비동기 코드를 작성할 때 async/await을 활용하면 큰 도움이 될 것 같다.