본문 바로가기
Study/JS

JavaScript 기초 강의 5편: 비동기 프로그래밍과 Promise, async/await

by wawManager 2024. 12. 5.
728x90

1. 비동기 프로그래밍의 필요성

비동기 프로그래밍은 네트워크 요청, 파일 읽기, 타이머 등 시간이 소요되는 작업이 실행되는 동안 코드가 멈추지 않고 다른 작업을 계속할 수 있도록 합니다. 이를 통해 사용자 경험이 향상되고 프로그램의 효율성이 높아집니다.

예제: 비동기 작업의 필요성

console.log("작업 1 시작");

setTimeout(() => {
    console.log("비동기 작업 완료");
}, 2000);

console.log("작업 2 시작");

// 출력:
// 작업 1 시작
// 작업 2 시작
// 비동기 작업 완료 (2초 후)

2. 콜백 지옥(Callback Hell)

비동기 작업을 콜백 함수로 중첩하여 사용하면 코드의 가독성이 떨어지고, 유지 보수가 어려워지는 콜백 지옥(callback hell) 문제가 발생할 수 있습니다.

콜백 지옥 예제

setTimeout(() => {
    console.log("1단계 완료");
    setTimeout(() => {
        console.log("2단계 완료");
        setTimeout(() => {
            console.log("3단계 완료");
        }, 1000);
    }, 1000);
}, 1000);

3. Promise의 개념

Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체입니다. Promise는 콜백 지옥을 해결하고, 가독성 있는 비동기 코드를 작성하는 데 유용합니다.

Promise 기본 사용법

const myPromise = new Promise((resolve, reject) => {
    let success = true; // 조건에 따라 성공/실패

    if (success) {
        resolve("작업이 성공했습니다!");
    } else {
        reject("작업이 실패했습니다.");
    }
});

myPromise
    .then(result => {
        console.log(result); // "작업이 성공했습니다!"
    })
    .catch(error => {
        console.log(error);
    })
    .finally(() => {
        console.log("Promise 작업이 완료되었습니다.");
    });

코드 설명

  • resolve: 작업이 성공했을 때 호출.
  • reject: 작업이 실패했을 때 호출.
  • .then(): resolve된 값을 처리.
  • .catch(): reject된 에러를 처리.
  • .finally(): 작업의 성공 여부와 관계없이 항상 실행.

4. async/await

async/await는 Promise 기반의 비동기 작업을 더 간결하고 가독성 있게 작성할 수 있게 해줍니다. async 키워드는 함수 앞에 붙으며, 이 함수는 항상 Promise를 반환합니다. await 키워드는 Promise가 완료될 때까지 대기하고, Promise의 결과를 반환합니다.

async/await 기본 예제

async function fetchData() {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("에러 발생:", error);
    }
}

fetchData();

코드 설명

  • **await**는 fetch() 함수가 Promise를 반환하기 때문에 사용됩니다.
  • try/catch 블록을 통해 오류를 처리할 수 있습니다.

async/await의 장점

  • 가독성이 높아지고, 코드 흐름이 동기식 코드와 유사하게 작성됩니다.
  • **try/catch**를 사용하여 에러 처리를 더 직관적으로 할 수 있습니다.

5. 실전 예제: 연속된 비동기 작업 처리

예제: 비동기 함수 호출 순서 제어

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

async function processSteps() {
    console.log("1단계 시작");
    await delay(1000);
    console.log("2단계 시작");
    await delay(1000);
    console.log("3단계 시작");
    await delay(1000);
    console.log("모든 단계 완료");
}

processSteps();
// 출력:
// 1단계 시작
// (1초 후)
// 2단계 시작
// (1초 후)
// 3단계 시작
// (1초 후)
// 모든 단계 완료

코드 설명

  • delay() 함수는 지정된 시간(ms)만큼 기다리는 Promise를 반환합니다.
  • **await**를 사용해 단계별로 실행을 제어하며, async 함수 내에서 순차적으로 실행됩니다.

요약

이번 강의에서는 비동기 프로그래밍의 개념과 콜백 함수의 한계를 극복하는 Promiseasync/await를 배웠습니다. Promise를 사용하면 비동기 작업을 깔끔하게 관리할 수 있고, async/await를 사용하면 가독성이 높은 코드로 비동기 작업을 처리할 수 있습니다. 다음 강의에서는 JavaScript에서 DOM을 심화적으로 조작하고, 동적 이벤트 핸들링을 다뤄보겠습니다.

728x90