일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- IntelliJ
- group by
- oracle
- 리눅스
- JPA
- docker
- MariaDB
- analytics4
- Exception
- DBMS
- git
- 트랜잭션
- Javascript
- 오블완
- 자바
- rsync
- PostgreSQL
- 호이스팅
- mysql
- 추상클래스
- 티스토리챌린지
- Python
- mssql
- Linux
- spring
- SQL
- 명령어
- java
- 차이점
- MongoDB
- Today
- Total
hanker
JavaScript - 비동기 프로그래밍 (Promise, async / await) 본문
Single Thread 방식으로 실행되는 JavaScript에서 비동기 처리방법은 Promise와 async / await 가 있다.
이번 글에서는 매일 써도 어려운 비동기 프로그래밍에 대해서 알아보자.
1. 비동기 프로그래밍이란?
JavaScript는 싱글 스레드 기반 언어이기 때문에 한 번에 하나의 작업만 실행이 가능하다.
예외로 네트워크 요청, 파일 읽기, 타이머 같은 작업은 비동기 방식으로 실행된다.
// 동기 코드 (순차 실행)
console.log("Start");
console.log("Processing...");
console.log("End");
// -- 출력 결과 --
// Start
// Processing...
// End
// 비동기 코드 (비순차 실행)
console.log("Start");
setTimeout(() => {
console.log("Async Task Complete");
}, 2000);
console.log("End");
// -- 출력 결과 --
// Start
// End
// Async Task Complete
2. 콜백 함수와 콜백 지옥
과거 Promise와 async / await 이 없을 때에 콜백 함수를 사용하여 비동기 처리를 했었다.
이러한 비동기 처리를 연속해서 수행할 때에 콜백 지옥(callback hell)을 맛보게 된다.
2-1. 콜백 함수
콜백 함수는 다른 함수의 인자로 전달되어 특정 작업이 끝난 후 호출되는 함수를 말한다.
ES6 이전 비동기 작업을 효율적으로 처리하기 위해 콜백함수를 사용한다.
setTimeout(function() {
console.log("1초 후에 실행됩니다.");
}, 1000);
위 코드로 예를 들면, 첫 번째 인자로 콜백 함수를 받고, 두 번째 인자로 지연시간을 받아 해당 시간이 지난 후 콜백 함수를 실행하게 된다.
function fetchData(callback) {
// 1초 후에 데이터를 받아왔다고 가정
setTimeout(() => {
const data = { id: 1, name: "John Doe" };
callback(data);
}, 1000);
}
// fetchData에 콜백 함수를 전달하여 데이터를 처리
fetchData(function(data) {
console.log("받은 데이터:", data);
});
위 코드에서 fetchData 함수는 데이터를 받아온 후 전달받은 콜백 함수를 호출하여 데이터를 처리한다.
2-2. 콜백 지옥(callback hell)
비동기 작업이 여러 단계로 연속해서 수행될 때, 콜백 함수를 중첩하여 사용하게 되는데,
이렇게 되면 코드의 가독성, 유지보수가 어려워진다.
function asyncOperation1(callback) {
setTimeout(() => {
console.log("Operation 1 완료");
callback("data1");
}, 1000);
}
function asyncOperation2(data, callback) {
setTimeout(() => {
console.log("Operation 2 완료");
callback(data + " -> data2");
}, 1000);
}
function asyncOperation3(data, callback) {
setTimeout(() => {
console.log("Operation 3 완료");
callback(data + " -> data3");
}, 1000);
}
asyncOperation1(function(result1) {
asyncOperation2(result1, function(result2) {
asyncOperation3(result2, function(result3) {
console.log("최종 결과:", result3);
});
});
});
위 코드처럼 많은 들여쓰기가 되는데, 이를 멸망의 피라미드(pyramid of doom) 라고 부른다.
3. Promise란?
위와 같은 문제(콜백 지옥)를 해결하기 위해 등장한 것이 비동기 작업을 처리해주는 Promise이다.
Promise는 성공(resolve) 또는 실패(reject) 상태를 가진다.
또한 .then()과 .catch()를 통해 비동기 작업을 순차적으로 처리할 수 있다.
function asyncOperation1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Operation 1 완료");
resolve("data1");
}, 1000);
});
}
function asyncOperation2(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Operation 2 완료");
resolve(data + " -> data2");
}, 1000);
});
}
function asyncOperation3(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Operation 3 완료");
resolve(data + " -> data3");
}, 1000);
});
}
asyncOperation1()
.then(result1 => asyncOperation2(result1))
.then(result2 => asyncOperation3(result2))
.then(result3 => console.log("최종 결과:", result3))
.catch(err => console.error(err));
4. async / await 사용하기
async / await는 비동기 코드를 동기처럼 더 쉽게 다룰 수 있도록 도와준다.
async function doOperations() {
try {
const result1 = await asyncOperation1();
const result2 = await asyncOperation2(result1);
const result3 = await asyncOperation3(result2);
console.log("최종 결과:", result3);
} catch (err) {
console.error(err);
}
}
doOperations();
정리
콜백 함수는 중첩이 많아지면 콜백 지옥이 발생하는데,
이를 해결하기 위해 Promise / .then() , async/await을 사용하여 비동기 작업을 더 효율적으로 처리하면 된다.
'JavaScript' 카테고리의 다른 글
JavaScript - 실행 컨텍스트와 콜 스택(Call Stack) (0) | 2025.02.04 |
---|---|
JavaScript - this 키워드 (현재 실행 중인 환경에 따라 다른 객체를 참조) (1) | 2025.01.30 |
JavaScript - 호이스팅(Hoisting) (0) | 2025.01.29 |
JavaScript - 스코프(Scope)와 클로저(Closure) (0) | 2024.12.27 |
JavaScript - JavaScript의 디버깅과 개발 도구 활용 (1) | 2024.12.21 |