- 자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용
👉하지만 콜백지옥(callback hell)로 인해 가독성이 나쁘며 발생한 에러 처리가 곤란
* 콜백지옥(callback hell) : 콜백 함수를 중첩하여 사용할 때 코드가 복잡해지고 가독성이 저하되는 현상
step1(function(value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
step5(value4, function(value5) {
// value5를 사용하는 처리
});
});
});
});
});
- ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스를 도입
- 프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있음!
- 프로미스는 Promise 생성자 함수를 통해 인스턴스화함
- Promise 생성자 함수는 비동기 작업을 수행할 콜백 함수를 인자로 전달받는데
이 콜백 함수는 resolve와 reject 함수를 인자로 전달받음- resolve : 비동기 작업이 성공했을때 호출
- reject : 비동기 작업이 실패했을때 호출
// Promise 객체의 생성
const promise = new Promise((resolve, reject) => {
// 비동기 작업을 수행한다.
if (/* 비동기 작업 수행 성공 */) {
resolve('result');
}
else { /* 비동기 작업 수행 실패 */
reject('failure reason');
}
});
- 프로미스의 처리 결과를 가지고 후속 처리 메서드의 인수로 전달
Promise 후속 처리 메서드🎈
🔸Promise.prototype.then
- 첫번째 콜백 함수 : 비동기 처리가 성공했을때 호출되는 성공 처리 콜백 함수
- 두번째 콜백 함수 : 비동기 처리가 실패했을때 호출되는 실패 처리 콜백 함수(가독성이 좋지 않음, catch 메서드 권장)
//성공했을때
new Promise(resolve => resolve('faulfilled'))
.then(v => console.log(v), e => console.error(e)); // fulfilled
//실패했을때
new Promise((_, reject) => reject(new Error('rejected')))
.then(v => conose.log(v), e => console.error(e)); // Error : rejected
🔸Promise.prototype.catch
- 한개의 콜백 함수를 인수로 전달받음
- catch 메서드의 콜백 함수는 프로미스가 rejected상태인 경우만 호출
//실패했을때
new Promise((_, reject) => reject(new Error('rejected')))
.catch(e => console.error(e)); // Error : rejected
🔸Promise.prototype.finally
- 한개의 콜백 함수를 인수로 전달받음
- finally 메서드의 콜백 함수는 프로미스의 성공 또는 실패에 상관없이 무조건 한번 호출
- 프로미스의 상태와 상관없이 공통적으로 수행해야 할 처리 내용이 있을 때 유용
new Promise(() => {})
.finally(() => console.log('finally')); // finally
Promise 정적 메서드🎈
🔸Promise.resolve / Promise.reject
- 이미 존재하는 값을 래핑하여 프로미스를 생성하기 위해 사용
- Promise.resolve 메서드는 인수로 전달받은 값을 resolve하는 프로미스를 생성
//const resolvedPromise = new Promise(resolve => resolve([1, 2, 3]));
//resolvedPromise.then(console.log); // [ 1, 2, 3 ]
//위와 동일
const resolvedPromise = Promise.resolve([1, 2, 3]);
resolvedPromise.then(console.log); // [ 1, 2, 3 ]
//const rejectedPromise = new Promise((resolve, reject) => reject(new Error('Error!')));
//rejectedPromise.catch(console.log); // Error: Error!
//위와 동일
const rejectedPromise = Promise.reject(new Error('Error!'));
rejectedPromise.catch(console.log); // Error: Error!
🔸Promise.all
- 전달받은 모든 프로미스를 병렬로 처리
이때 모든 프로미스의 처리가 종료될 때까지 기다린 후 아래와 모든 처리 결과를 resolve 또는 reject
- 프로미스가 담겨 있는 배열 등의 이터러블을 인자로 전달 받음
- 전달받은 모든 프로미스를 병렬로 처리
- 그 처리 결과를 resolve하는 새로운 프로미스를 반환
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log) // [ 1, 2, 3 ]
.catch(console.log);
🔸Promise.race
- Promise.all 메소드와 동일하게 프로미스가 담겨 있는 배열 등의 이터러블을 인자로 전달 받음
- Promise.all 메소드처럼 모든 프로미스를 병렬 처리하는 것이 아니라
가장 먼저 처리된 프로미스가 resolve한 처리 결과를 resolve하는 새로운 프로미스를 반환
Promise.race([
new Promise((resolve, reject) => setTimeout(() => reject(new Error('Error 1!')), 3000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error('Error 2!')), 2000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error('Error 3!')), 1000))
]).then(console.log)
.catch(console.log); // Error: Error 3!
🔸Promise.allSettled
- 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받음
- 전달받은 프로미스가 모두 settled상태(비동기 처리가 수행된 상태)가 되면 처리결과를 배열로 반환
Promise.allSettled([
new Promise(resolve => setTimeout(() => resolve(1), 2000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error!')),1000))
]).then(console.log);
/* 출력
{
"status": "fulfilled",
"value": 1
},// [object Object]
{
"status": "rejected",
"reason": {}
}]
*/
Promise - JavaScript | MDN
Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
developer.mozilla.org
'자바스크립트' 카테고리의 다른 글
[JS]프로토타입 (2) | 2024.10.10 |
---|---|
[JS]비동기(async/await) (0) | 2024.10.10 |
[JS]단축평가 (1) | 2024.10.09 |
[JS]자료구조(Set,Map) (1) | 2024.10.09 |
[JS]디스트럭처링 할당(구조분해 할당) (1) | 2024.10.08 |