728x90
안녕하세요. 오늘은 콜백지옥을 타개하기 위해 나온 자바스크립트 프로미스에 대해 알아보도록 하겠습니다. (유튜브 '코드팩토리'님의 강의 일부를 참고하였습니다.)
프로미스(Promise)란?
비동기 작업의 최종 완료 또는 실패를 나타내는 자바스크립트 객체
프로미스는 비동기 작업이 완료될 때 결과 값을 반환하거나 작업이 실패할 경우 에러를 전달함
프로미스 상태 3가지
- 대기(Pending) - 초기 상태로, 이행하거나 거부되지 않은 상태
- 이행(Fulfilled) - 작업이 성공적으로 완료된 상태
- 거부(Rejected) - 작업이 실패한 상태
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('완료');
}, 2000);
});
console.log(promise); // 이 시점에서 상태는 'pending'
// 2초 후에는 프로미스가 fulfilled 상태가 됨
setTimeout(() => {
console.log(promise); // 이 시점에서 상태는 'fulfilled'
}, 3000);
- 처음에 console.log(promise)를 호출했을 때, 프로미스가 아직 resolve되거나 reject되지 않았기 때문에 pending 상태로 출력되며 이 상태는 비동기 작업이 완료될 때까지 유지됨
- 2초 후에 resolve가 호출되면, 프로미스는 fulfilled 상태로 변경됨. 3초 후에 console.log(promise)를 호출하면 fulfilled 상태와 함께 resolve된 값을 출력
프로미스 기본 형태
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업 수행
if (/* 작업이 성공했을 경우 */) {
resolve('작업 성공'); // 성공 시 호출
} else {
reject('작업 실패'); // 호출 시 호출
}
});
- 'resolve'는 작업이 성공했을 때 호출되어 프로미스를 이행 상태로 전환
- 'reject'는 작업이 실패했을 때 프로미스를 거부 상태로 전환함
프로미스 사용 방법
기본 사용법
프로미스를 사용할 때 주로 'then' 메서드와 'catch' 메서드, finally() 메서드를 사용해 정의함
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('작업이 완료되었습니다.');
}, 2000);
});
timeoutPromise
.then((result) => {
console.log(result); // 작업이 완료되었습니다.
})
.catch((error) => {
console.log(error); // 에러가 발생하면 에러 메시지 출력
})
.finally(() => {
console.log('finally 실행');
}
- then() : 프로미스가 성공적으로 완료되면('resolve'가 호출되면) then() 메서드의 콜백 함수가 실행됨
- catch() : 프로미스가 실패하면('reject'가 호출되면) catch() 메서드의 콜백 함수가 실행됨
- finally() : 프로미스가 완료된 후 성공(fulfilled)이든 실패(rejected)든 관계없이 항상 실행됨. finally()는 자원을 정리하거나 후속 작업을 설정하는 데 유용함
체이닝(Chaining)
프로미스는 then() 메서드를 체이닝하여 여러 비동기 작업을 순차적으로 수행할 수 있음
const getPromise = (seconds) => new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${seconds}초 후 완료`);
}, seconds * 1000);
});
getPromise(1)
.then((result) => {
console.log(result); // '1초 후 완료'
return getPromise(2); // 새로운 프로미스 반환
})
.then((result) => {
console.log(result); // '2초 후 완료'
return getPromise(3); // 새로운 프로미스 반환
})
.then((result) => {
console.log(result); // '3초 후 완료'
})
.catch((error) => {
console.error('에러 발생:', error);
});
- 위 코드에서 'getPromise' 함수는 입력받은 초(seconds) 이후에 'resolve'를 호출하는 프로미스를 반환함
- 각 then() 메서드는 이전 프로미스가 성공적으로 완료되었을 때 호출되며 새로운 프로미스를 반환하여 다음 then() 메서드로 연결됨
에러 처리
프로미스에서 에러가 발생하면 'reject()'가 호출되고 이를 처리하기 위해 'catch()' 메서드를 사용함. 'catch()'는 체인의 마지막에 위치하며 이전 단계에서 발생한 모든 에러를 처리함
const getPromiseWithError = (seconds) => new Promise((resolve, reject) => {
setTimeout(() => {
reject(`${seconds}초 후 에러 발생`);
}, seconds * 1000);
});
getPromiseWithError(2)
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error('에러:', error); // '에러: 2초 후 에러 발생' 출력
});
프로미스의 정적 메소드(Static Method)
Promise.all()
- 여러 프로미스를 병렬로 실행하고 모든 프로미스가 완료될 때까지 기다린 후 결과를 반환
- 하나의 프로미스라도 실패하면 전체가 실패로 처리됨
Promise.all([
getPromise(1),
getPromise(4),
getPromise(2)
])
.then((results) => {
console.log(results); // ['1초 후 완료', '4초 후 완료', '2초 후 완료'] 출력
// 4초 뒤 실행. 가장 느린 함수 기준으로 then이 불림
})
.catch((error) => {
console.error('에러 발생:', error);
});
Promise.race()
- 여러 프로미스를 병렬로 실행하고 가장 먼저 완료되는 프로미스의 결과를 반환
- 하나의 프로미스라도 완료되면 즉시 해당 결과를 반환
Promise.race([
getPromise(1),
getPromise(2),
getPromise(3)
])
.then((result) => {
console.log(result); // '1초 후 완료' 출력 (가장 빨리 완료된 프로미스)
})
.catch((error) => {
console.error('에러 발생:', error);
});
Promise.allSettled()
- 모든 프로미스가 완료될 때까지 기다리며 각각의 프로미스 결과를 반환함
- 프로미스가 성공했는지 실패했는지 여부와 관계없이 결과를 반환
Promise.allSettled([
getPromise(1),
getPromiseWithError(2),
getPromise(3)
])
.then((results) => {
console.log(results);
/*
[
{ status: 'fulfilled', value: '1초 후 완료' },
{ status: 'rejected', reason: '2초 후 에러 발생' },
{ status: 'fulfilled', value: '3초 후 완료' }
]
*/
});
프로미스 개념 예전부터 정리하고 싶었는데 드디어 했네요ㅠㅠㅠㅠㅠㅠㅎ!
728x90
'Languages > JavaScript' 카테고리의 다른 글
[JS] 호이스팅(Hoisting) (0) | 2024.09.09 |
---|---|
[JS] 비동기 프로그래밍(3) : Async/Await (0) | 2024.08.23 |
[JS] 비동기 프로그래밍(1) : 콜백 함수(Callback Function) (0) | 2024.08.23 |
[JS] 배열 메소드(Array Method) 총정리 (0) | 2024.08.22 |
[JS] 데이터 타입 총정리 (0) | 2024.08.21 |