Promise
자바스크립트에서 Promise API는 비동기 API이다.
따라서 setTimeout은 Task queue에 저장되는 것과 달리, Promise API는 Job queue에 저장된다.
job que가 task que보다 우선순위 높기 때문에 아래와 같은 결과가 나온다.
setTimeout(() => {
consoloe.log("타임 아웃1")
}, 0);
Promise.resolve().then( () => console.log("프로미스1"));
setTimeout(() => {
consoloe.log("타임 아웃2")
}, 0);
Promise.resolve().then( () => console.log("프로미스2"));
// 출력
// 프로미스1 프로미스2
// 타임 아웃1 타임 아웃2
Promise의 작업 상태
new Promise( )로 프로미스를 생성하고 종료 될 때까지 3가지 상태를 갖는다.
(1) Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다. 이때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.
new Promise(function(resolve, reject) {
// ...
});
(2) Fulfilled(이행 == 완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 된다.
new Promise(function(resolve, reject) {
resolve();
});
이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
console.log(resolvedData); // 100
});
(3) Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.
new Promise(function(resolve, reject) {
reject();
});
실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다. (reject보다는 catch를 추천함)
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
Promise.resolve와 Promise.reject
Promise.resolve함수는 Promise를 바로 반환한다.
Promise.reject함수는 실패한 Promise를 바로 반환한다.
Promise
.resolve(10)
.then(console.log)
Promise
.reject("Error")
.catch(console.log)
Promise로 then, catch, finally 코드
then ( ) 메서드: 성공했을 때, 실행할 콜백함수를 인자로 넘긴다.
catch ( ) 메서드: 실패했을 때, 실행할 콜백함수를 인자로 넘긴다.
finally ( ) 메서드: 성공/실패 여부와 상관없이 모두 실행할 콜백 함수를 인자로 넘긴다.
function getData() {
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
if (response) {
resolve(response);
}
reject(new Error("Request is failed"));
});
});
}
// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
console.log(data); // response 값 출력
}).catch(function(err) {
console.error(err); // Error 출력
}).finally(function() {
console.log("promise 종료"); // 성공/실패 여부에 관계없이 항상 실행
});
Promise Chaning ( 여러 개의 프로미스 연결하기)
then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다. 따라서, 아래처럼 체인 형식으로 구현이 가능해진다.
new Promise(function(resolve, reject){
setTimeout(function() {
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result); // 1
return result + 10;
})
.then(function(result) {
console.log(result); // 11
return result + 20;
})
.then(function(result) {
console.log(result); // 31
});
프로미스 객체를 하나 생성하고 setTimeout()을 이용해 2초 후에 resolve()를 호출하는 예제
resolve()가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 .then()의 로직으로 넘어감.
첫 번째 .then()에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 .then() 으로 넘겨줌.
두 번째 .then()에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 .then()으로 넘겨줌.
마지막 .then()에서 최종 결과 값 31을 출력.
Promise.all
Promise 배열을 받아 모두 성공시 각 Promise의 resolved 값을 배열로 반환한다.
하나의 promise라도 실패할 시, 가장 먼저 실패한 promise의 실패 이유를 반환한다.
Promise.all([
promise1,
promise2,
promise3
])
.then(values => {
console.log("모두 성공", values)
})
.catch(e => {
console.log("하나라도 실패", e)
})
'프론트엔드 > javascript' 카테고리의 다른 글
[javascript] Axios API 사용하기 (0) | 2022.10.11 |
---|---|
[javascript] 비동기3 - async/await, fetch API (Post 정보 조합하기) (0) | 2022.10.05 |
[javascript] 비동기1 - 콜백함수 (1) | 2022.10.04 |
[javascpript] 실행 컨텍스트 (execution context) (1) | 2022.09.28 |
[javascript] 네비게이션 기능 구현하기 (0) | 2022.09.27 |