2025-01-26T02:15:33

This commit is contained in:
2025-01-26 02:15:33 +09:00
parent f43f6328c0
commit f867e689aa
22 changed files with 2702 additions and 213 deletions

View File

@@ -0,0 +1,136 @@
# 비동기 프로그래밍 (Asynchronous Programming)
자바스크립트는 단일 스레드 기반의 언어로, 한 번에 하나의 작업만 실행할 수 있는 싱글 스레드 모델을 따릅니다. 하지만 비동기 프로그래밍을 통해 여러 작업을 동시에 처리할 수 있는 것처럼 보이게 하고, 효율적인 프로그램을 만들 수 있습니다.
비동기 프로그래밍은 **시간이 오래 걸리는 작업(예: 파일 읽기, 데이터베이스 요청, API 호출)**을 실행하는 동안 다른 작업을 멈추지 않고 동시에 처리할 수 있도록 합니다.
자바스크립트의 **이벤트 루프(Event Loop)**와 **콜백 큐(Callback Queue)**는 비동기 작업을 가능하게 하는 핵심 메커니즘입니다.
## 이벤트 루프(Event Loop)
이벤트 루프는 비동기 작업이 완료되었을 때 콜백 함수를 호출하여 실행할 수 있도록 관리합니다.
* 콜 스택(Call Stack): 실행할 함수가 저장되는 공간.
* 콜백 큐(Callback Queue): 비동기 작업이 완료된 후 실행 대기 중인 콜백 함수들이 대기하는 공간.
이벤트 루프는 **콜 스택이 비어 있을 때** 콜백 큐에서 작업을 가져와 실행합니다.
## 비동기 처리 방식 비교
* 콜백 함수
- 간단한 비동기 작업에 적합
- 콜백 지옥 발생 가능
* Promise
- 가독성이 좋고 에러 처리가 간편
- 체인 길어질 경우 가독성 저하
* async/await
- 동기식 코드처럼 작성 가능, 가독성 뛰어남
- 여러 개의 비동기 처리 병렬 실행은 불편
## 콜백 함수 (Callback Function)
콜백 함수는 함수의 인자로 전달되어 특정 작업이 완료된 후 실행됩니다.
```javascript
console.log("시작");
setTimeout(() => {
console.log("3초 후 실행");
}, 3000);
console.log("끝");
// 시작
// 끝
// 3초 후 실행
```
### 콜백 지옥 (Callback Hell)
콜백 함수가 중첩되면서 코드가 복잡하고 읽기 어려워지는 문제를 콜백 지옥이라고 합니다.
```javascript
setTimeout(() => {
console.log("1단계");
setTimeout(() => {
console.log("2단계");
setTimeout(() => {
console.log("3단계");
}, 1000);
}, 1000);
}, 1000);
```
## 프로미스 (Promise)
ES6에서 도입된 Promise는 비동기 작업을 보다 깔끔하게 처리할 수 있는 방법입니다.
Promise는 대기(Pending) → 성공(Fulfilled) → 실패(Rejected) 상태를 가집니다.
```javascript
const myPromise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve("작업 성공!");
} else {
reject("작업 실패!");
}
});
myPromise
.then(result => {
console.log(result); // 출력: 작업 성공!
})
.catch(error => {
console.error(error);
});
```
* resolve: 비동기 작업이 성공적으로 완료되었을 때 호출되는 함수입니다.
* reject: 비동기 작업이 실패했을 때 호출되는 함수입니다.
* then: Promise가 성공적으로 완료되었을 때 실행될 함수를 전달합니다.
* catch: Promise가 실패했을 때 실행될 함수를 전달합니다.
* Promise.resolve: 이미 완료된 값을 가지는 Promise를 생성합니다.
* Promise.reject: 실패한 Promise를 생성합니다.
### Promise 체이닝
then 메서드는 새로운 Promise를 반환하므로, 여러 개의 then 메서드를 연결하여 비동기 작업을 순차적으로 실행할 수 있습니다.
```javascript
promise
.then(result => {
return result + ' 추가 작업';
})
.then(result => {
console.log(result); // '작업 완료! 추가 작업' 출력
})
.catch(error => {
console.error(error);
});
```
### 병렬 처리
비동기 작업을 병렬로 실행하려면 **Promise.all**이나 **Promise.allSettled**을 사용할 수 있습니다.
```javascript
const promise1 = new Promise(resolve => setTimeout(() => resolve("1초 후 완료"), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("2초 후 완료"), 2000));
Promise.all([promise1, promise2]).then(results => {
console.log(results); // 출력: ["1초 후 완료", "2초 후 완료"]
});
```
* Promise.all: 여러 개의 Promise를 동시에 실행하고, 모든 Promise가 완료되었을 때 결과를 반환합니다.
* Promise.race: 여러 개의 Promise 중 가장 먼저 완료된 Promise의 결과를 반환합니다.
## async와 await
Promise를 더욱 간결하게 사용할 수 있는 방법입니다. async와 await는 비동기 작업을 동기적인 코드처럼 읽기 쉽게 작성할 수 있도록 도와줍니다.
```javascript
function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve("데이터 로드 완료!");
}, 2000);
});
}
async function getData() {
console.log("데이터 요청 중...");
const result = await fetchData();
console.log(result); // 출력: 데이터 로드 완료!
}
getData();
```
* async: 함수가 비동기 함수임을 나타냅니다.
* await: Promise가 완료될 때까지 기다리고, 그 결과를 반환합니다.