Promise
Promise
상점에 들어가서 상품을 주문했을 때 언제 어떻게 나올지 모르는 상품을 기다릴 때 사용한다.
완성 혹은 실패했을 때 연락이 오게 만드는 함수
const pr = new Promise((resolve, reject) => {
// code....
});
인수는 resolve와 reject이다.
resolve는 성공한 경우
reject는 실패한 경우
이렇게 어떤 일이 완료된 이후 실행되는 함수를 callback함수라고 한다.
- new Promise 생성자가 반환하는 promise 객체는 state와 result를 프로퍼티로 갖는다.
- state는 초기 pending(대기) 상태이고 result는 undefined이며, resolve(value)가 호출되면 state는 fulfilled가 된다.
- 이때 result는 resolve함수가 전달된 값(value)이다.
- 만약 실패하면 state는 rejected가되고 result는 reject함수로 전달된 error이다.
판매자의 코드
성공
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 3000);
});
state: pending / result: undefined
3초 후
state: fulfilled/ result: ‘OK’
실패
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
reject('error..');
}, 3000);
});
state: pending / result: undefined
3초 후
state: rejected/ result: ‘error’
소비자의 코드
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 3000)
});
// 여기부터 소비자의 코드
pr.then(
function(result){
console.log(result + ' 가지러 가자.');
},
function(err){
console.log('다시 만들어주세요.');
}
);
첫번째 인수는 promise가 이행되었을 때 실행되고 result에는 OK가 들어옴
두번째 인수는 promise가 거부되었을 때 실행되고 err에는 에러 값이 들어온다.
resolve로 실행되었기 때문에 두번째 callback을 실행되지 않는다.
catch
reject일 때만 실행된다.
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 3000);
});
pr.then(
function(result){
console.log(result + ' 가지러 가자.');
}
).catch(
function(err){
console.log('다시 만들어주세요.');
}
);
catch로 명확하게 구분하는 것이 가독성에도 좋고 첫번째 함수를 실행했다가 나는 에러도 잡아줄 수 있다.
finally
이행이든 거부든 처리가 완료되면 항상 실행된다.
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 3000);
});
pr.then(
function(result){
console.log(result + ' 가지러 가자.');
}
).catch(
function(err){
console.log('다시 만들어주세요.');
}
).finally(
function(){
console.log('---주문 끝---');
}
);
예문
const pr = new Promise((resolve, reject) => { setTimeout(() => {
resolve("OK");
}, 1000);
});
console.log("시작");
pr.then((result) => {
console.log(result);
}).catch((err) => {
console.log(err);
}).finally(() => {
console.log("끝");
});
시작
1초후
OK / reject라면 Error: error…
끝
3개의 상품, promise 사용 X
const f1 = (callback) => {
setTimeout(() => {
console.log("1번 주문완료");
}, 1000);
};
const f2 = (callback) => {
setTimeout(() => {
console.log("2번 주문완료");
}, 2000);
};
const f3 = (callback) => {
setTimeout(() => {
console.log("3번 주문완료");
}, 3000);
};
console.log('시작');
f1(() => {
f2(() => {
f3(() => {
console.log('끝');
});
});
});
이렇게 뎁스가 깊어지면서 계속 callback을 호출하는 것을 callback hell이라고 한다.
3개의 상품, promise 사용
const p1 = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("1번 주문 완료");
}, 1000);
});
}
const p2 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("2번 주문 완료");
}, 2000);
});
}
const p3 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("3번 주문 완료");
}, 3000);
});
}
console.log('시작');
p1()
.then((res) => p2(res))
.then((res) => p3(res))
.then((res) => console.log(res));
.catch(console.log)
.finally(() => {
console.log('끝');
});
promise가 연결되어 있는 것을 promise chaining이라고 한다.
2번 실패 예문
const p1 = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("1번 주문 완료");
}, 1000);
});
}
const p2 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
rej("2번 주문 실패");
}, 2000);
});
}
const p3 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("3번 주문 완료");
}, 3000);
});
}
console.log('시작');
p1()
.then((res) => p2(res))
.then((res) => p3(res))
.then((res) => console.log(res));
.catch(console.log)
.finally(() => {
console.log('끝');
});
시작
1번 주문 완료
2번 주문 실패
끝
promise.all
한번에 주문하고 가장 오래걸리는 상품의 시간이 지나면 모든 제품을 받을 수 있다.
const p1 = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("1번 주문 완료");
}, 1000);
});
}
const p2 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("2번 주문 성공");
}, 2000);
});
}
const p3 = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("3번 주문 완료");
}, 3000);
});
}
console.time("x"); // 시간을 재는 방법
Promise.all([p1(), p2(), p3()]).then((res) => {
console.log(res);
console.timeEnd("x");
});
하지만 실패하면 어떠한 데이터도 얻을 수 없다.
따라서 정보 하나라도 누락되면 페이지를 보여주면 안되는 경우에 사용할 수 있다.
promise.race
하나라도 완료되면 멈춘다.
console.time("x"); // 시간을 재는 방법
Promise.all([p1(), p2(), p3()]).then((res) => {
console.log(res);
console.timeEnd("x");
});
1번이 완료되면 멈춘다.
용량이 큰 이미지들을 로딩할 때 하나라도 완료되면 이미지를 보여 줄 때
댓글남기기