Notice
Recent Posts
반응형
«   2025/11   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
바로가기

Jin's IT Story

JavaScript 비동기 처리 방식과 Promise, Async Await 개념 완벽 정리 본문

DevBasics: 개발 개념 기초 다지기

JavaScript 비동기 처리 방식과 Promise, Async Await 개념 완벽 정리

JinBytes 2025. 10. 27. 21:50

목차


    반응형

    비동기 흐름을 구조적으로 표현

     

    JavaScript는 웹 개발에서 가장 널리 사용되는 언어 중 하나로, 특히 비동기 처리(asynchronous processing) 기능이 중요한 역할을 합니다. 사용자는 버튼을 클릭하거나 데이터를 요청할 때 즉각적인 응답을 기대하지만, 서버와의 통신이나 파일 처리처럼 시간이 걸리는 작업은 페이지 전체를 멈추게 할 수 있습니다.

     

    이러한 문제를 해결하기 위해 JavaScript는 비동기 처리 모델을 통해 효율적이고 부드러운 사용자 경험을 제공합니다.

     

    본 글에서는 비동기의 정의, 동기 방식과의 차이점, 그리고 JavaScript에서 비동기를 구현하는 주요 방법인 콜백(Callback), 프로미스(Promise), async/await 문법에 대해 체계적으로 알아보겠습니다.

     

     

     

     

     

    1. 비동기의 정의

    비동기(asynchronous)란 프로그램의 흐름이 특정 작업의 완료를 기다리지 않고 다른 작업을 동시에 수행할 수 있는 구조를 의미합니다.


    예를 들어 서버로 데이터를 요청했을 때, 요청이 완료될 때까지 기다리지 않고 다음 명령을 실행하는 것이 비동기 처리입니다. 반면, 동기(synchronous)는 한 작업이 끝나야 다음 작업이 시작되는 구조로, 코드 실행 순서가 직렬로 이어집니다.

     

    JavaScript는 단일 스레드(single-thread) 언어로, 한 번에 하나의 작업만 수행할 수 있습니다. 그러나 이벤트 루프(Event Loop)콜백 큐(Callback Queue) 메커니즘을 통해 동시에 여러 작업이 수행되는 것처럼 보이는 비동기 처리를 지원합니다.

     

    즉, JavaScript는 실제로 여러 스레드를 사용하는 것이 아니라, 비동기 이벤트를 효율적으로 관리하여 사용자가 멈춤 없는 인터랙션을 경험하도록 합니다.

    2. 동기와 비동기의 차이

    동기(Synchronous) 방식은 코드가 작성된 순서대로 실행됩니다.
    예를 들어, A 작업이 끝나야 B 작업이 실행되는 구조입니다. 이러한 방식은 단순하지만, 네트워크 요청처럼 시간이 오래 걸리는 작업이 있을 때 전체 프로그램이 멈추는 단점이 있습니다.

     

    반면, 비동기(Asynchronous) 방식은 A 작업이 완료되기를 기다리지 않고 B, C 작업을 먼저 수행할 수 있습니다. A 작업이 완료되면 나중에 콜백 함수를 통해 결과를 처리하는 식으로 동작합니다.

     

    예시를 통해 살펴보겠습니다.

    // 동기 예시
    console.log("1");
    console.log("2");
    console.log("3");
    // 출력: 1, 2, 3
    // 비동기 예시
    console.log("1");
    setTimeout(() => console.log("2"), 1000);
    console.log("3");
    // 출력: 1, 3, 2
     

    위의 예시처럼 setTimeout은 일정 시간이 지난 뒤 실행되므로, JavaScript는 “2”를 기다리지 않고 다음 코드를 먼저 실행합니다.

    이것이 바로 비동기 처리의 핵심입니다.

     

     

     

     

     

    3. JavaScript 비동기 처리의 핵심 메커니즘

    JavaScript의 비동기 동작은 콜 스택(Call Stack), 이벤트 루프(Event Loop), 태스크 큐(Task Queue) 구조로 이루어져 있습니다.

    • 콜 스택(Call Stack): 실행 중인 코드가 쌓이는 공간으로, 함수가 호출되면 스택에 push되고, 완료되면 pop됩니다.
    • Web APIs: 브라우저 환경에서 제공하는 비동기 기능(API). 예를 들어 setTimeout, fetch, addEventListener 등이 있습니다.
    • 태스크 큐(Task Queue): 비동기 작업의 콜백들이 대기하는 공간입니다.
    • 이벤트 루프(Event Loop): 콜 스택이 비면 태스크 큐의 작업을 스택으로 이동시켜 실행합니다.

    이 과정을 통해 JavaScript는 비동기적으로 여러 작업을 자연스럽게 처리할 수 있습니다.

    4. 비동기 처리 방식 ① 콜백 함수(Callback Function)

    콜백 함수란 다른 함수의 인자로 전달되어 특정 시점에 실행되는 함수를 의미합니다.
    비동기 함수가 작업을 마치면, 콜백 함수를 호출하여 결과를 전달합니다.

     
    function getData(callback) {
      setTimeout(() => {
        callback("데이터 로드 완료");
      }, 1000);
    }
    
    getData((result) => {
      console.log(result);
    });

     

    콜백 방식은 간단하지만, 여러 비동기 함수를 연속적으로 실행해야 할 때 중첩 구조가 발생하며, 이를 흔히 콜백 지옥(callback hell) 이라고 부릅니다.

    5. 비동기 처리 방식 ② 프로미스(Promise)

    Promise는 콜백 지옥 문제를 해결하기 위해 도입된 ES6(ECMAScript 2015)의 비동기 처리 객체입니다.
    Promise는 비동기 작업의 성공(fulfilled), 실패(rejected), 대기(pending) 상태를 관리하며, then, catch, finally 메서드로 결과를 다룹니다.

    const getData = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("데이터 성공적으로 로드됨");
      }, 1000);
    });
    
    getData
      .then((data) => console.log(data))
      .catch((err) => console.error(err))
      .finally(() => console.log("작업 종료"));
     

    Promise는 비동기 흐름을 명확하게 제어할 수 있으며, .then() 체이닝을 통해 순차적으로 작업을 이어갈 수 있습니다.

     

     

     

     

     

    6. 비동기 처리 방식 ③ Async / Await

    ES8(ECMAScript 2017)에서 도입된 async/await는 Promise 기반 비동기 처리를 동기 코드처럼 작성할 수 있게 해주는 문법입니다.

    async function fetchData() {
      try {
        const data = await new Promise((resolve) => {
          setTimeout(() => resolve("데이터 로드 성공"), 1000);
        });
        console.log(data);
      } catch (error) {
        console.error(error);
      }
    }
    
    fetchData();
     

    await 키워드는 Promise가 처리될 때까지 기다리며, 코드의 가독성을 크게 높입니다.
    즉, 콜백의 복잡한 중첩 없이 순차적 로직을 명확하게 표현할 수 있어 현대적인 비동기 처리 방식의 표준으로 자리 잡았습니다.

     

    JavaScript의 비동기 처리는 현대 웹 애플리케이션의 성능과 사용자 경험을 결정짓는 핵심 요소입니다.
    비동기는 단순히 “동시에 실행되는 것”이 아니라, 효율적인 이벤트 루프 구조를 통한 비차단형(Non-blocking) 처리 방식을 의미합니다.

     

    초기에는 콜백 함수로 시작했지만, Promise와 async/await의 발전을 통해 코드의 가독성과 유지보수성이 크게 향상되었습니다.
    결국 비동기 처리를 이해하는 것은 JavaScript 개발자에게 있어 필수적인 기초이며, 이를 잘 다루면 서버 통신, 데이터 로딩, API 응답 등 다양한 상황에서 더 효율적이고 유연한 코드를 작성할 수 있습니다.

    반응형