비동기 프로그래밍
비동기 프로그래밍
개요
JavaScript는 단일 스레드 기반의 언어로, 동기적 코드 실행이 기본이지만 네트워크 요청, 파일 시스템 작업, 사용자 입력 처리와 같은 비차단(non-blocking) 작업을 위해 비동기 프로그래밍 모델을 채택하고 있습니다. 이 문서에서는 JavaScript의 비동기 처리 방식의 역사적 발전과 최신 표준을 중심으로 설명하며, 이벤트 루프, 콜백 함수, 프로미스, async/await의 개념과 활용 방법을 다룹니다.
콜백 함수 (Callback Functions)
개념
콜백 함수는 비동기 작업 완료 후 실행되는 함수로, JavaScript 초기부터 사용된 전통적인 방법입니다. 예시:
function fetchData(callback) {
setTimeout(() => {
callback('데이터 수신 완료');
}, 1000);
}
fetchData((result) => {
console.log(result); // "데이터 수신 완료" (1초 후)
});
한계
- 콜백 지옥(Callback Hell): 중첩된 콜백으로 인해 코드 가독성이 저하되는 문제
- 에러 처리 복잡성: 각 콜백에서 별도의 에러 처리 필요
프로미스 (Promise)
상태
프로미스는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체로, 다음 세 가지 상태를 가집니다: | 상태 | 설명 | |------|------| | pending | 대기 상태 (초기 상태) | | fulfilled | 성공적으로 완료됨 | | rejected | 실패 상태 |
then과 catch
fetchData()
.then((result) => {
console.log('성공:', result);
})
.catch((error) => {
console.error('실패:', error);
});
정적 메서드
메서드 | 설명 |
---|---|
[Promise.all](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B0%9C%EB%B0%9C/Promise.all)() |
모든 프로미스가 성공할 때까지 대기 |
[Promise.race](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B0%9C%EB%B0%9C/Promise.race)() |
가장 먼저 완료된 프로미스 결과 반환 |
[Promise.allSettled](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B0%9C%EB%B0%9C/Promise.allSettled)() |
모든 프로미스의 결과 반환 (성공/실패 관계 없이) |
[Promise.any](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B0%9C%EB%B0%9C/Promise.any)() |
가장 먼저 성공한 프로미스 결과 반환 |
async/await
기본 문법
async 함수는 암시적으로 프로미스를 반환하며, await 키워드를 사용해 비동기 코드를 동기적으로 표현할 수 있습니다:
async function getData() {
try {
const result = await fetchData();
console.log('결과:', result);
} catch (error) {
console.error('에러:', error);
}
}
에러 처리
[try/catch](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B0%9C%EB%B0%9C/try%2Fcatch)
구문으로 명확한 에러 핸들링 가능unhandledrejection
이벤트 리스너로 전역 에러 처리
내부 동작
async/await은 프로미스 기반의 문법적 설탕(syntactic sugar)으로, Babel과 같은 트랜스파일러는 이를 프로미스 체인으로 변환합니다.
고급 개념
이벤트 루프와 마이크로태스크
- 마이크로태스크 큐: 프로미스 콜백은 이벤트 루프의 해당 단계에서 우선 처리됨
- 우선순위: 마이크로태스크 > 타이머 > I/O 이벤트
동시성 모델
- 이벤트 기반 아키텍처: 이벤트 발생 시 등록된 핸들러 실행
- Web Workers: CPU 집약적 작업을 위한 별도 스레드 (브라우저 환경)
참고 자료
이 문서는 JavaScript의 비동기 처리 방식을 체계적으로 이해하고 현대 웹 개발에서의 활용 방법을 설명하기 위해 제작되었습니다. 추가적인 학습을 위해 MDN 문서와 공식 스펙을 참조하시기 바랍니다.
이 문서는 AI 모델(qwen-3-235b-a22b)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.