코딩 스쿨 JavaScript

언어선택 : HTMLCSSJAVAJAVASCRIPTMYSQLSQL PHP

JavaScript Asynchronous

JavaScript Asynchronous Programming: 비동기 프로그래밍 개념과 사용법

JavaScript 비동기 프로그래밍동기적 실행과 달리, 특정 작업이 완료될 때까지 대기하지 않고 그동안 다른 작업을 수행할 수 있도록 합니다. 이는 웹 애플리케이션에서 HTTP 요청, 파일 처리, 타이머, 이벤트 핸들러와 같은 시간이 걸리는 작업을 효율적으로 처리할 수 있게 해줍니다. JavaScript의 비동기 처리는 주로 콜백 함수, 프라미스(Promise), 그리고 **async/await**를 통해 구현됩니다.

이 가이드는 JavaScript에서 비동기 프로그래밍의 기본 개념주요 사용법을 설명합니다.


1. 비동기 프로그래밍의 기본 개념

비동기 프로그래밍은 작업이 즉시 완료되지 않을 경우, 대기하지 않고 그 작업이 완료되었을 때 콜백 함수프라미스를 통해 처리 결과를 받아오는 방식입니다. JavaScript싱글 스레드에서 동작하기 때문에, 비동기 프로그래밍을 통해 시간이 오래 걸리는 작업이 전체 프로그램의 실행을 블로킹하지 않도록 합니다.

1.1. 동기적 프로그래밍 예시

function syncTask() {
    console.log('Task 1');
    console.log('Task 2');
}

syncTask();
// Task 1
// Task 2 (순차적으로 실행됨)

1.2. 비동기적 프로그래밍 예시

function asyncTask() {
    console.log('Task 1');
    setTimeout(() => {
        console.log('Task 2 (Executed after 2 seconds)');
    }, 2000);
    console.log('Task 3');
}

asyncTask();
// Task 1
// Task 3 (즉시 실행)
// Task 2 (2초 후에 실행)

  • 비동기 작업setTimeout() 함수는 2초 후에 실행되며, 그동안 **다른 작업(Task 3)**이 즉시 실행됩니다.
  • 비동기 작업순차적 흐름을 방해하지 않고, 결과를 나중에 처리할 수 있습니다.

2. 콜백 함수로 비동기 처리

  • *콜백 함수(Callback)**는 비동기 작업이 완료된 후 나중에 호출될 함수입니다. 콜백 함수는 비동기 작업의 결과를 처리하기 위한 가장 기본적인 방법입니다.

2.1. 콜백 함수 예시

function fetchData(callback) {
    setTimeout(() => {
        const data = 'Sample Data';
        callback(data);  // 비동기 작업 완료 후 콜백 함수 호출
    }, 2000);  // 2초 후에 실행
}

function displayData(data) {
    console.log(`Fetched data: ${data}`);
}

fetchData(displayData);  // Fetched data: Sample Data (2초 후 출력)

  • fetchData() 함수는 비동기 작업을 수행한 후, 콜백 함수를 호출하여 데이터를 전달합니다.
  • 콜백 함수는 비동기 작업이 완료된 후에 나중에 실행됩니다.

2.2. 콜백 헬 문제

  • *콜백 헬(Callback Hell)**은 비동기 작업이 여러 개 중첩되면서, 코드가 복잡하고 가독성이 떨어지는 문제입니다. 이 문제를 해결하기 위해 프라미스나 **async/await*를 사용하는 것이 더 바람직합니다.
setTimeout(() => {
    console.log('Task 1 complete');
    setTimeout(() => {
        console.log('Task 2 complete');
        setTimeout(() => {
            console.log('Task 3 complete');
        }, 1000);
    }, 1000);
}, 1000);
// 중첩된 비동기 작업으로 인해 코드가 복잡해짐


3. 프라미스(Promise)를 사용한 비동기 처리

  • *프라미스(Promise)**는 비동기 작업이 성공하거나 실패했을 때 그 결과를 처리하는 객체입니다. 프라미스는 더 읽기 쉬운 코드중첩된 콜백의 문제를 해결하는 데 도움이 됩니다.

3.1. 프라미스 기본 구조

  • resolve(): 비동기 작업이 성공했을 때 호출.
  • reject(): 비동기 작업이 실패했을 때 호출.
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve('Data fetched successfully!');
        } else {
            reject('Failed to fetch data.');
        }
    }, 2000);
});

myPromise
    .then((data) => {
        console.log(data);  // Data fetched successfully!
    })
    .catch((error) => {
        console.log(error);  // 에러 발생 시 실행
    });

  • 프라미스비동기 작업의 결과성공(resolve) 또는 **실패(reject)**로 처리할 수 있습니다.
  • *then()*은 성공 시 실행되며, **catch()*는 실패 시 실행됩니다.

3.2. 프라미스 체이닝

프라미스를 사용하면 비동기 작업체인으로 연결하여 순차적으로 처리할 수 있습니다.

const fetchData = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('Data 1');
        }, 1000);
    });
};

fetchData()
    .then((data) => {
        console.log(data);  // Data 1
        return 'Data 2';
    })
    .then((data) => {
        console.log(data);  // Data 2
        return 'Data 3';
    })
    .then((data) => {
        console.log(data);  // Data 3
    });

  • 각 **then()*에서 다음 작업을 반환하고, 순차적으로 실행됩니다.
  • 이를 통해 비동기 작업체인 방식으로 처리할 수 있습니다.

4. async/await를 사용한 비동기 처리

  • *async/await*는 프라미스더 직관적이고 동기 코드처럼 작성할 수 있게 해줍니다. **await*는 프라미스가 해결될 때까지 기다렸다가, 결과를 처리할 수 있습니다.

4.1. async/await 사용 예시

const fetchData = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('Sample Data');
        }, 2000);
    });
};

async function displayData() {
    const data = await fetchData();
    console.log(data);  // Sample Data (2초 후 출력)
}

displayData();

  • async 함수는 **await*를 사용할 수 있는 비동기 함수입니다.
  • *await*는 프라미스가 완료될 때까지 기다리며, 그 이후의 코드는 동기 방식으로 작성됩니다.

4.2. async/await와 오류 처리

  • *async/await*는 try...catch 구문을 사용하여 오류 처리를 할 수 있습니다.
const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('Error fetching data');
        }, 2000);
    });
};

async function displayData() {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.log(error);  // Error fetching data
    }
}

displayData();

  • try...catch 블록을 사용해 프라미스 실패 시 발생하는 에러를 처리할 수 있습니다.

5. 비동기 처리의 장점과 단점

5.1. 장점

  • 비동기 작업을 처리하면서 다른 작업을 동시에 수행할 수 있어 성능 최적화가 가능.
  • HTTP 요청, 파일 입출력, 타이머와 같은 작업에서 블로킹을 방지.
  • *async/await*를 통해 가독성 높은 코드를 작성할 수 있음.

5.2. 단점

  • 비동기 코드동기 코드보다 복잡할 수 있음.
  • 콜백 함수를 중첩하면 콜백 헬이 발생할 수 있음.
  • 비동기 오류 처리가 복잡해질 수 있음.

JavaScript 비동기 프로그래밍싱글 스레드 환경에서 시간이 걸리는 작업을 효율적으로 처리할 수 있게 해주는 중요한 개념입니다. 비동기 작업은 콜백 함수, 프라미스(Promise), async/await 같은 다양한 방법을 통해 처리됩니다.

  • 콜백 함수는 비동기 작업의 결과를 처리하는 기본 방법이지만, 콜백 헬 문제를 일으킬 수 있습니다.
  • *프라미스(Promise)**는 비동기 작업의 성공 또는 실패를 처리하며, 프라미스 체이닝을 통해 여러 비동기 작업을 순차적으로 처리할 수 있습니다.
  • *async/await*는 프라미스를 동기식 코드처럼 작성할 수 있게 하며, 가독성이 높은 비동기 코드를 작성할 수 있습니다.

JavaScript 비동기 프로그래밍은 성능 최적화비동기 작업 처리에서 필수적인 개념입니다.


copyright ⓒ 스타트코딩 all rights reserved.
이메일 : startcodingim@gamil.com