Promise란 무엇인지 설명해주실 수 있을까요?
Promise는 자바스크립트에서 비동기 작업을 더 효과적으로 다루기 위한 객체입니다. 비동기 작업은 일반적으로 네트워크 요청, 파일 읽기/쓰기, 데이터베이스 쿼리 등과 같이 시간이 걸리는 작업을 의미하며, 이러한 작업은 결과를 기다리는 동안 프로그램이 다른 작업을 계속할 수 있도록 해줍니다.
Promise가 콜백 함수보다 비동기 작업을 효과적으로 다루는 이유는 다음과 같습니다:
가독성과 유지보수성 향상: Promise는 비동기 코드를 더 읽기 쉽고 구조화하기 쉽게 만듭니다. 콜백 헬(callback hell) 또는 콜백 지옥(callback hell)을 방지하고 비동기 코드를 평평하게 유지할 수 있습니다.
비동기 작업의 순서화: Promise를 사용하면 비동기 작업의 순서를 쉽게 정의할 수 있습니다. then 메서드를 사용하여 작업이 이전 작업이 완료된 후에 실행되도록 할 수 있습니다.
에러 처리의 간결성: Promise는 catch 메서드를 사용하여 전역 에러 핸들러를 설정하고 오류를 효과적으로 처리할 수 있습니다. 이로써 오류가 누락되지 않고 처리됩니다.
성공 및 실패 상태 관리: Promise는 성공 및 실패 상태를 갖고 있어 작업의 완료 또는 실패를 명확하게 추적할 수 있습니다. 이로써 작업의 성공 또는 실패를 처리하거나 재시도할 수 있습니다.
콜백 중첩 방지: Promise를 사용하면 비동기 작업을 중첩하는 대신 순차적으로 연결할 수 있습니다. 이로써 코드가 복잡성을 높이는 콜백 중첩을 방지할 수 있습니다.
Promise 체이닝: Promise는 then 메서드를 이용하여 여러 비동기 작업을 연결하고 순차적으로 실행할 수 있는 "Promise 체이닝"을 허용합니다. 이로써 코드가 더 명확하고 예측 가능해집니다.
ES6 이후 표준 기능: Promise는 ECMAScript 6 (ES6)부터 표준으로 포함되어 있으며, 현대적인 자바스크립트 환경에서 널리 지원되므로 플랫폼 간 이식성이 뛰어납니다.
콜백 함수를 사용한 비동기 코드는 가독성이 낮고 오류 처리가 어려워 복잡성을 증가시킬 수 있습니다. Promise는 이러한 문제들을 해결하기 위해 설계되었으며, 현대적인 자바스크립트 애플리케이션에서 비동기 작업을 더 효과적으로 다루는 데 도움을 줍니다.
Promise 객체는 다음과 같은 특징을 가집니다:
상태(State): Promise는 세 가지 상태를 가집니다
대기(pending): 초기 상태, 비동기 작업의 완료 또는 실패를 기다립니다.
이행(fulfilled): 비동기 작업이 성공적으로 완료됨을 나타냅니다.
거부(rejected): 비동기 작업이 실패함을 나타냅니다.
값(Value): Promise는 비동기 작업이 완료되면 어떤 값(또는 결과)을 가질 수 있습니다. 이 값은 fulfilled 상태일 때 사용됩니다.
오류(Error): 비동기 작업이 실패할 경우, 오류 정보(일반적으로 에러 객체)를 포함합니다. 이 정보는 rejected 상태일 때 사용됩니다.
예시
// Promise 생성자를 사용하여 비동기 작업을 처리하는 함수 정의
function delayedTask(duration) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const randomValue = Math.random();
if (randomValue >= 0.5) {
resolve(`Task completed in ${duration}ms`);
} else {
reject(`Task failed in ${duration}ms`);
}
}, duration);
});
}
// delayedTask 함수를 호출하여 Promise 객체를 얻고, 비동기 작업을 시작
delayedTask(2000)
.then((result) => {
console.log(result); // 성공한 경우
})
.catch((error) => {
console.error(error); // 실패한 경우
});
delayedTask 함수는 Promise를 반환하며, setTimeout 함수를 사용하여 비동기 작업을 모방합니다. 비동기 작업은 임의로 성공 또는 실패로 처리됩니다. Promise는 성공할 경우 resolve 콜백을 호출하여 결과를 반환하고, 실패할 경우 reject 콜백을 호출하여 오류를 반환합니다.
다음으로, then 메서드를 사용하여 Promise가 성공한 경우 결과를 처리하고, catch 메서드를 사용하여 실패한 경우 오류를 처리합니다.
이 예제는 간단한 Promise의 사용 사례를 보여줍니다. 물론 실제로는 네트워크 요청, 파일 읽기/쓰기, 데이터베이스 쿼리와 같은 실제 비동기 작업을 처리하는 데 사용됩니다.
같은 코드를 콜백함수로 작성
function delayedTaskUsingCallback(duration, successCallback, errorCallback) {
setTimeout(() => {
const randomValue = Math.random();
if (randomValue >= 0.5) {
successCallback(`Task completed in ${duration}ms`);
} else {
errorCallback(`Task failed in ${duration}ms`);
}
}, duration);
}
// 비동기 작업을 콜백 함수로 처리
delayedTaskUsingCallback(
2000,
(result) => {
console.log(result); // 성공한 경우
},
(error) => {
console.error(error); // 실패한 경우
}
);
위의 코드에서 delayedTaskUsingCallback 함수는 콜백 함수를 사용하여 비동기 작업을 처리합니다. setTimeout 함수를 사용하여 비동기 작업을 수행하고, 작업이 성공하면 successCallback 함수를 호출하고 작업이 실패하면 errorCallback 함수를 호출합니다. 이렇게 콜백 함수를 사용하면 Promise와 유사한 비동기 작업 처리를 수행할 수 있습니다.
비교적 간단한 작업에 대해서는 콜백 함수를 사용하여 비동기 코드를 처리할 수 있지만, 더 복잡한 상황에서는 Promise나 async/await와 같은 패턴이 더 효과적이고 가독성이 높을 수 있습니다.