Promise란?
“A promise is an object that may produce a single value some time in the future”
Promise란 자바스크립트 비동기처리에서 사용되는 객체이며, 함수 호출 또는 비동기연산이 완료되었을 때, 이후에 처리할 함수나 에러를 처리하기 위한 함수를 설정하는 모듈이다. 비동기처리란, 특정코드가 실행완료될때까지 기다리지 않고 다른 코드를 먼저 실행하는 처리방식이다. ES6에 도입되었고 비동기 처리가 가장 많이 일어나는 XMLHTTPRequest 처리에서 유용하게 사용된다.
그럼 Promise가 왜 필요해서 사용하는건데?
Promise 이전에는 비동기처리를 위해 콜백함수를 사용했다. 그러나 콜백함수를 연속적으로 사용하는 경우, 연속적으로 비동기 코드를 처리할 때, 콜백지옥(Callback Hell)이 발생할 수 있다.
setTimeout(function() { // callback1
console.log('How are you/');
setTimeout(function() { // callback2
console.log('I am fine.');
setTimeout(function() { // callback3
console.log('Thank you');
setTimeout(function() { // callback4
console.log('And you?');
}, 3000);
}, 3000);
}, 3000);
}, 3000);
위 코드는 가독성도 낮을 뿐만 아니라 로직의 변경이 까다롭고 힘들다는 단점이 있다.
이러한 코드를 Promise와 async를 통해 개선할 수 있다.
Promise의 3가지 상태
Promise에는 3가지 상태가 존재한다.
- Pending : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled : 비동기 처리가 완료되어 프로미스가 결과값을 반환해준 상태
- Rejected : 비동기 처리가 실패하거나 오류가 발생한 상태
Pending상태에서 비동기처리가 성공하면 resolve 되었다고 하고, 실패하면 reject 되었다고 한다.
먼저 Callback함수를 사용한 비동기처리 함수를 만들어서 실행해보자.
function isCorrect(number, res, rej){
setTimeout(() => {
if(typeof number === 'number') {
res(number >=0 ? "양수" : "음수") // resolve
} else {
rej("값이 아님") // reject
}
}, 2000);
}
isCorrect(10, (res)=> {
console.log("성공 : ", res)
}, (err) => {
console.log("실패 : ", rej)
}
);
isCorrect함수에 number와 resolve, reject 콜백함수를 전달하고 setTimeout 함수를 사용해 2초뒤에 실행되는 비동기함수를 만들어봤다. isCorrect의 첫번째 인자가 number type이면 "성공 : "양수" : "음수"" 가 출력되고 number type이 아니면 "실패..." 가 실행된다.
아래의 isCorrect() Callback 함수로 만들어본 비동기 처리 함수가 잘 작동됨을 확인해볼 수 있다.
Promise를 활용해보자
function isCorrect(number) {
const executor = (res, rej) => {
setTimeout(() => {
if (typeof number === 'number') {
res(number >=0 ? "양수" : "음수") // resolve
} else {
rej("값이 아님") // reject
}
}, 2000)
}
const asyncTask = new Promise(executor);
return asyncTask;
}
isCorrect(100);
executor라는 함수는 res와 rej 2개의 파라미터를 받는다. executor함수는 비동기작업을 실질적으로 실행시켜주는 함수이다.
이제 isCorrect함수에서 executor를 실행시키면 된다.
비동기 자체를 저장할 asyncTask를 만들어 new 키워드를 사용해 Promise객체를 생성하고 생성자로 비동기 함수의 실질적인 실행자 함수 executor를 인자로 넘겨준다. 그리고 asyncTask를 return해준다.
const asyncTask = new Promise(executor);
return asyncTask;
이제 isCorrect함수는 Promise를 반환하게 되었다. 함수가 Promise를 반환한다는 것은 이 함수는 비동기작업을 하고 그 작업의 결과를 Promise객체로 반환받아서 사용할 수 있는 함수가 되었다라는 의미이다.
Promise 반환 객체를 사용해보자
function isCorrect(number) {
const executor = (res, rej) => {
setTimeout(() => {
if (typeof number === 'number') {
res(number >=0 ? "양수" : "음수") // resolve
} else {
rej("값이 아님") // reject
}
}, 2000)
}
const asyncTask = new Promise(executor);
return asyncTask;
}
const res = isCorrect(100);
res
.then((res) => {
console.log("작업 성공 : ", res);
})
.catch((err) => {
console.log("작업 실패 : ", err);
})
위 코드는 then과 catch를 사용하여 resolve를 사용했을 때 결과값을 then의 callback 함수(res) 에서 받을 수 있고,
reject를 사용했을 때 결과값을 catch(err) 에서 받을 수 있다.
'TIL' 카테고리의 다른 글
[JS] API & fetch (0) | 2023.07.01 |
---|---|
[JS] async & await (0) | 2023.06.30 |
[JS] Javascript Engine Heap & Call Stack (0) | 2023.06.24 |
[JS] 동기 & 비동기 (0) | 2023.06.20 |
[JS] 스프레드 연산자(spread operator) (0) | 2023.06.18 |