[JavaScript] 17. Promise

Zero·2023년 2월 13일
0

JavaScript

목록 보기
17/35

promise 란 ?

promise를 실생활에 빗대어 설명하면 어느 한 상점에 손님이 물건을 요구하고 해당 상점은 물건을 제작합니다. 손님은 요구한 물건이 나오기 전까지 10초마다 물건의 완성여부를 묻는 행동을 한다고 가정했을 때, 상점측은 "아니요" , "만들다가 실패했어요" 등의 대답을 해줄 수 있다. 이렇게 10초마다 물어보는 비효율적인 상황에서 효율적인 방법을 찾아보면 ? 손님이 자신의 전화번호를 상점에 남기고 완성되거나 실패하면 결과를 자신의 번호로 알려달라 라고 하는 것이 효율적이겠지요. 이런 행위를 promise라고 하고 js에서도 해당 기능을 하는 promise 함수가 있습니다.

promise 사용법

const pr = new Promise((resolve,reject) => {
 	// code
}
  • 다음와 같이 Promise 함수는 두 개의 인수를 가지는데 , resolve (성공) 와 reject (실패) 입니다.
  • 성공시에는 resolve 함수를 실행해주며 , 실패시 reject 함수를 실행해줍니다.
  • 이렇게 어떤일이 완료된 이후에 실행되는 함수를 call back함수라고 합니다 !

  • 다음과 같이 초기 promise 함수는 다음과 같은 값을 갖습니다.
    - state : pending (대기 상태)
    - result : undefined

  • 이후 resolve(value) 가 실행되면 다음과 같은 값을 갖습니다.
    - state : fulfilled (성공)
    - result : value(인자로 넘긴 value)

  • 만약 reject(error) 가 실행되면 다음과 같은 값을 갖습니다.
    - state : rejected(거부됨)
    - result : error


--> 코드는 다음과 같이 이행되었을 때와 ,실패했을 때를 구분하여 작성합니다.

.finally ( function() {} ) 를 추가로 붙여주면 성공 , 실패 여부와 상관없이 실행되는 함수를 만들 수 있다.

콜백 헬 (콜백 지옥)

const f1 = (callback) => {
	setTimeout(function() {
    	console.log("1번 주문 완료");
      	callback();
    },3000);
};
const f2 = (callback) => {
	setTimeout(function() {
    	console.log("2번 주문 완료");
      	callback();
    },3000);
};
const f3 = (callback) => {
	setTimeout(function() {
    	console.log("3번 주문 완료");
      	callback();
    },3000);
};

console.log("시작");
f1(function(){
	f2(function() {
    	f3(function() {
   			console.log("끝");      
        });
    });
});
  • 다음과 같이 작성하면 콜백함수를 통해 실행이 잘 이루어지지만 , 깊은 콜백함수를 통해 실행된다.
  • 이와 같이 콜백의 depth 가 깊어지는 것을 콜백 지옥 (콜백 헬 ) 이라고 한다.

그렇다면 이 문제를 Promise를 이용하여 해결해보자

const f1 = (message) => {
	return new Promise((res,rej)=>{
      setTimeout(function() {
        res("1번 주문 완료");
      },1000);
    });
};
const f2 = (message) => {
  	console.log(message);
	return new Promise((res,rej)=>{
      setTimeout(function() {
        res("2번 주문 완료");
      },3000);
    });
};
const f3 = (message) => {
  	console.log(message);
	return new Promise((res,rej)=>{
      setTimeout(function() {
        res("3번 주문 완료");
      },2000);
    });
};

console.log("시작");
f1
.then(res => f2(res))
.then(res => f3(res))
.then(res => console.log(res));
.catch(console.log)
.finally(()=>{
	console.log("끝");
});
  • 위 처럼 promise가 연결되는 것을 프로미스 체이닝 Promise chaining이라고 합니다.

조금 더 빠른 promise 처리

그렇다면 위 코드에서 f1,f2,f3의 setTimeout 설정 시간을 보면 1초 ,3초 ,2초로 시간대가 모두 다르다. 따라서 모두 다 실행하려면 총 6초가 걸리는 셈인데, 이를 조금 더 빨리 처리할 순 없을까 ?

--> 해결하려면 세개의 promise를 동시에 처리하면서 가장 오래걸리는 시간을 기준으로 한다면

3초 안에 모두 끝낼 수 있지 않겠는가 ??? 이를 위해서 promise all을 사용하면 된다

promise all

Promise.all([f1(),f2(),f3()])
.then(res => {
	console.log(res);
});

이처럼 배열로 promise를 넘겨주면 세 개의 프로미스가 끝나야 then 이 실행되게 된다.

reject를 반환하면 페이지 오류가 발생하기 때문에

해당 코드는 페이지를 보여주거나 에러가 발생했을 때는 아예 보여주지 않는 경우에 사용하는 것이 바람직하다.

promise race

promise all 과 사용법은 같지만 다른 부분은 race 란 단어를 통해 유추할 수 있듯이
프로미스들이 경주를 하여 가장 먼저 끝낸 프로미스만 실행되고 코드가 종료된다.
따라서 만약 f2에 reject를 걸어놨을 때 promise race 를 이용하면 f1()이 성공적으로 실행되고 f2()의 reject 가 반환되기 전 이미 끝나버린다.

Promise.race([f1(),f2(),f3()])
.then(res => {
	console.log(res);
});

0개의 댓글