본문 바로가기
IT/Javascript Basic

[Javascript] 초급 개념 Async / Await — 비동기 처리의 직관적인 문법

by Echinacea 2025. 4. 16.
반응형

 

 

목차

  1. 비동기 처리란?
  2. async / await란 무엇인가?
  3. 주요 문법과 사용 방법
  4. 예제 코드
  5. 출력 결과 및 설명
  6. 응용 예시: API 호출 시 사용
  7. 요약 및 마무리

 

 

 


1. 비동기 처리란?

자바스크립트는 단일 스레드(single-thread) 언어입니다. 즉, 한 번에 하나의 작업만 처리할 수 있습니다. 하지만 웹 애플리케이션에서는 서버 요청, 파일 읽기, 타이머 등 시간이 오래 걸리는 작업들이 많기 때문에 비동기 처리가 필요합니다.

 

⏱️ 동기 vs 비동기

  • 동기(synchronous): 작업이 순차적으로 실행되며, 앞 작업이 끝나야 다음 작업이 실행됩니다.
  • 비동기(asynchronous): 특정 작업을 백그라운드에서 처리하고, 그 사이 다른 코드를 실행할 수 있습니다.

과거에는 콜백(callback) → 프라미스(Promise) → 그리고 지금의 async / await로 진화해 왔습니다.


 

 

2. async / await란 무엇인가?

async와 await는 프라미스(Promise) 기반의 비동기 코드를 동기 코드처럼 읽기 쉽게 만드는 문법입니다.

 

🔹 async 함수

  • 함수 앞에 async 키워드를 붙이면 해당 함수는 자동으로 Promise를 반환합니다.
  • 함수 내부에서 에러가 발생하면 자동으로 reject된 Promise로 처리됩니다.
  • 일반 함수처럼 호출하지만, 결과는 Promise이기 때문에 .then()이나 await로 받을 수 있습니다.
async function sayHello() {
  return "안녕하세요!";
}

sayHello().then(msg => console.log(msg)); // "안녕하세요!" 출력

 

🔹 await 표현식

  • await는 Promise가 처리될 때까지 기다립니다.
  • 반드시 async 함수 안에서만 사용할 수 있습니다.
  • await는 Promise가 resolve되면 결과 값을 반환하고, reject되면 예외가 발생합니다.
async function main() {
  const result = await Promise.resolve("완료!");
  console.log(result); // "완료!"
}

main();

 

 

✅ 장점

  • async/await를 사용하면 코드 흐름이 더 명확하고 직관적입니다.
  • 콜백 중첩이나 .then() 체인을 줄여 가독성이 높아집니다.

이 조합을 통해 복잡했던 비동기 로직을 마치 순차적인 동기 코드처럼 작성할 수 있습니다.

 

✨ 추가 예제 1: 에러 처리

async function getData() {
  try {
    const response = await fetch("https://invalid-url.com/data");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("에러가 발생했습니다:", error.message);
  }
}

getData();
  • 네트워크 에러나 잘못된 응답이 발생하면 catch 블록이 실행됩니다.

 

✨ 추가 예제 2: 여러 await 사용

async function fetchMultiple() {
  const user = await fetch("https://jsonplaceholder.typicode.com/users/1").then(res => res.json());
  const post = await fetch("https://jsonplaceholder.typicode.com/posts/1").then(res => res.json());

  console.log("사용자:", user.name);
  console.log("게시글 제목:", post.title);
}

fetchMultiple();
  • 순차적으로 두 개의 API를 호출하고 각 결과를 출력합니다.

 

 

3. 주요 문법과 사용 방법

// async 함수 선언
async function 함수이름() {
  const 결과 = await 비동기함수();
  console.log(결과);
}

// 또는 화살표 함수로
const 함수이름 = async () => {
  const 결과 = await 비동기함수();
  console.log(결과);
}

⚠️ await은 일반 함수나 전역 범위에서 직접 사용할 수 없습니다 (단, 최신 Node.js나 브라우저 콘솔에서는 지원됨).


 

4. 예제 코드

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function greetUser() {
  console.log("1. 사용자 정보 불러오는 중...");
  await delay(2000); // 2초 대기
  console.log("2. 환영합니다, 사용자님!");
}

greetUser();
console.log("3. 메인 로직 실행 중...");

 

✨ 추가 예제 1: 순차 처리 흐름 이해

async function stepByStep() {
  console.log("A. 시작");
  await delay(1000);
  console.log("B. 중간 처리");
  await delay(1000);
  console.log("C. 완료");
}

stepByStep();
  • 각 단계가 1초씩 지연되며 순서대로 실행됩니다.

 

✨ 추가 예제 2: 조건에 따른 비동기 처리

async function loginCheck(user) {
  if (!user) return "로그인 필요";
  const result = await Promise.resolve(`${user}님 로그인 성공`);
  return result;
}

loginCheck("홍길동").then(console.log); // "홍길동님 로그인 성공"
  • 조건에 따라 Promise 실행 여부를 제어할 수 있습니다.

 

 

5. 출력 결과 및 설명

1. 사용자 정보 불러오는 중...
3. 메인 로직 실행 중...
2. 환영합니다, 사용자님!

 

📌 설명

  • greetUser() 내부는 await 덕분에 2초간 대기 후 다음 줄을 실행합니다.
  • 하지만 greetUser() 호출 후 아래 코드(console.log("3..."))는 먼저 실행됩니다. 즉, 전체적으로는 비동기 처리되면서도 읽기 쉬운 코드가 된 것입니다.

 

 

6. 응용 예시: API 호출 시 사용

async function fetchUserData() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
    const data = await response.json();
    console.log("사용자 이름:", data.name);
  } catch (error) {
    console.error("에러 발생:", error);
  }
}

fetchUserData();

 

💡 설명

  • 실제 API 호출 시 fetch()는 비동기 함수이므로 await를 사용하여 처리합니다.
  • try-catch 블록을 사용하여 에러 처리도 깔끔하게 할 수 있습니다.

 

 

7. 요약 및 마무리

  • async / await는 비동기 코드를 더 직관적이고 가독성 좋게 작성할 수 있게 도와줍니다.
  • await는 Promise가 해결될 때까지 기다리며, async 함수 안에서만 사용 가능합니다.
  • 콜백 지옥이나 .then() 체인의 복잡함을 줄일 수 있어 현대 자바스크립트에서 필수적인 문법입니다.
  • 주의: 항상 try-catch로 오류를 처리하는 습관을 들이세요.

 

 

 

반응형

댓글