Promise
promise는 비동기 처리를 위해 사용되는 객체이다.
기존의 비동기 처리방식에서의 문제점(콜백 헬)을 보완하고자 도입되었다.
콜백 헬(Callback Hell) : 비동기 처리에 있어서 처리 순서를 보장하기 위해 여러 개의 콜백 함수가 중첩되는 현상
step1(function(value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
step5(value4, function(value5) {
// value5를 사용하는 처리
});
});
});
});
});
*callback hell은 코드의 가독성을 나쁘게 하고 복잡도를 증가시켜 실수를 유발하는 원인이 되며 에러 처리가 곤란하다.
Promise는 비동기 처리의 상태 정보를 갖고 있다.
- pending : 비동기 처리가 아직 수행되지 않은 상태
- fulfilled : 비동기 처리가 수행을 성공적으로 마친 상태
- rejected : 비동기 처리가 수행을 마쳤지만 실패한 상태
- settled : 비동기 처리가 수행을 마친 상태(성공, 실패 모두)
Promise 정적 메서드
- Promise.resolve()
- Promise.reject()
- Promise.all(Iterable)
- Promise.race(Iterable)
Promise생성자 함수는 객체를 생성할 때 resolve와 reject 메서드를 인자로 받게 된다.
생성된 Promise객체 내의 비동기 처리를 성공적으로 마쳤다면(fulfilled) resolve 메서드의 내용을 실행하고,
실패했다면(rejected) reject 메서드의 내용을 실행한다.
동시에 resolve와 reject메서드는 Promise 값을 반환해야 하기 때문에 존재하는 값을 Promise객체 값으로 래핑 해준다.
*Promise로 구현된 비동기 처리 함수는 항상 Promise 객체를 반환해야 한다.
let j = 13;
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function(){
if (j > 120) {
resolve(console.log("Success!"));
}
reject(console.log("Failed..."));
}, 2000);
});
//Failed...
Promise.all(Iterable)과 Promise.race(Iterable)은 아래에서 예제를 통해 설명하도록 한다.
Promise 후속처리 메서드
- Promise.prototype.then()
- Promise.prototype.catch()
then 메서드는 두 개의 콜백 함수를 인자로 전달받는다.
첫 번째 콜백 함수는 성공(fulfilled, resolve 함수가 호출된 상태) 시 호출되고
두 번째 함수는 실패(rejected, reject 함수가 호출된 상태) 시 호출된다.
catch 메서드는 예외(비동기 처리에서 발생한 에러와 then 메서드에서 발생한 에러)가 발생하면 호출된다.
*Promise 비동기 처리 중 발생한 에러 처리를 then 메서드에서 두 번째 인자로 처리해도 되지만
이런 방식으로 처리한다면 첫 번째 인자로 받은 콜백 함수의 에러를 처리하지 못하고 가독성에서도 좋지 않다.
*에러 처리 시에는 catch메서드를 사용하자!
Promise.all(Iterable)
Promise.all 메소드는 프로미스가 담겨 있는 배열 등의 Iterable을 인자로 전달 받는다.
그리고 전달받은 모든 프로미스를 병렬로 처리하고 그 처리 결과를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)
.catch(console.log);
// [ 1, 2, 3 ]
Promise.all([
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.all 참고
-
모든 프로미스의 처리가 성공하면 각각의 프로미스가 resolve 한 처리 결과를 배열에 담아 resolve 하는 새로운 프로미스를 반환한다. 이때 첫 번째 프로미스가 가장 나중에 처리되어도 Promise.all 메소드가 반환하는 프로미스는
첫번째 프로미스가 resolve 한 처리 결과부터 차례대로 배열에 담아 그 배열을 resolve 하는 새로운 프로미스를 반환한다.
즉, 처리 순서가 보장된다. - 프로미스의 처리가 하나라도 실패하면 가장 먼저 실패한 프로미스가reject 한 에러를 reject 하는 새로운 프로미스를 즉시 반환한다.
Promise.race(Iterable)
Promise.all 메소드와 동일하게 프로미스가 담겨 있는 배열 등의 Iterable을 인자로 전달 받는다.
그리고 Promise.race 메소드는 Promise.all 메소드처럼 모든 프로미스를 병렬 처리하는 것이 아니라
가장 먼저 처리된 프로미스가resolve 한처리 결과를resolve 하는새로운 프로미스를 반환한다.
Promise.race([
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)
.catch(console.log);
// 3
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!
참고
'개발 > Javascript' 카테고리의 다른 글
startsWith, endsWith, includes (0) | 2021.02.19 |
---|---|
비동기 통신(Ajax) 방식(XMLHttpRequest , Promise , Fetch API , async/await) (0) | 2021.02.14 |
Ajax (Asyncronous Javascript and XML) (0) | 2021.02.09 |
Event (0) | 2021.02.06 |
데이터 타입, 표준 내장 객체(Standard Built-in Object), 타입 변환 (0) | 2021.02.03 |