▶ JavaScript Async |
JavaScript Callbacks |
JavaScript Asynchronous |
JavaScript Promises |
JavaScript Async-Await |
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 비동기 프로그래밍은 성능 최적화와 비동기 작업 처리에서 필수적인 개념입니다.