Promise

2021. 2. 3. 19:33Front-end/Javascript

728x90
반응형

프로미스(promise)란?

- 프로미스는 자바스크립트 비동기 처리에 사용되는 객체(Object)이다.

- 비동기 처리: ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’을 의미함

- 프로미스를 사용하면 콜백 함수를 계속해서 불러서 코드의 가독성이 떨어지는 일명 '콜백 지옥'을 없이 쉽게 비동기 처리 가능

  -  프로미스는 정해진, 장시간의 기능을 수행하고 나서 정상적으로 기능이 수행이 되어졌다면 "성공의 메시지와 함께 결과 값을 전달"
  -  만약 기능을 수행하다가 예상치못한 문제가 발생했다면 "Error를 전달"

 

프로미스 학습에 중요한 포인트 2가지

1) State(상태)

2) Producer  VS Consumer

  - Producer(제공자): 우리가 원하는 데이터를 제공하는 사람

  - Consumer(소비자) : 제공된 데이터를 쓰는 사람(필요로 하는 사람)

 

프로미스의 상태

pending → fulfilled or rejected
• pending(보류): 초기 상태
• fulfilled(이행): 오퍼레이션을 성공적으로 다 끝내게 되면
• rejected(거부): 아니면 파일을 찾을 수가 없거나 네트워크에 문제가 생긴다면 

* 처음엔 “pending”(보류)였다 resolve가 호출되면 “fulfilled”, reject가 호출되면 “rejected”로 변한다

 

Producer VS Consumer

1) Producer

const promise = new Promise(function(resolve, reject){
  
})
const promise = new Promise((resolve, reject) =>{
  
})

(위의 두 코드는 같은 것이다. 이해를 돕기 위해 작성했다.)

new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, new Promise에 전달되는 함수는 executor(실행자, 실행함수) 라고 부른다. executor는 new Promise가 만들어질 때 자동으로 실행되는데, 결과를 최종적으로 만들어내는 제작 코드를 포함한다.

executor의 인수 resolve와 reject는 자바스크립트가 자체적으로 제공하는 콜백이다.

개발자는 resolve와 reject를 신경쓰지 않고 executor 안 코드만 작성하면 된다.

const promise = new Promise((resolve, reject) =>{
    //doing some heavy work (network, read files)
    console.log('doing something...');
})

 

이렇게 함수 안에 실행 코드를 적고 콘솔창을 확인해보면 'doing something...'이 바로 출력된다.

When new promise is created, the executor runs automatically.

(프로미스가 만들어질 때 executor가 자동으로 실행된다는 점을 염두해 두자.)

즉, 우리가 만든 함수가 바로 실행 된다는 것인데, 이 말인 즉슨, 만일 우리가 저 안에 네트워크 통신을 하는 코드를 작성했다면 프로미스가 만들어진 그 순간 바로 네트워크 통신을 수행하게 된다. 여기서 한 가지 우리가 배울 수 있는 중요한 포인트는, 만약 네트워크 요청을 사용자가 요구했을 때에만 처리해야 하는 경우라면 이런식으로 작성하게 되면 사용자가 요구하지도 않았는데 불필요한 네트워크 통신이 일어날 수 있을 것이다. 그래서 이 점을 조금 유의해서 공부해야 한다.

 

const promise = new Promise((resolve, reject) =>{
    //doing some heavy work (network, read files)
    console.log('doing something...');
    setTimeout(()=>{
        resolve('ellie');
    },2000);
})

일단, 이 프로미스 안에서 네트워크 통신을 하는 것 처럼 setTimeout을 이용해서 시간의 딜레이를 주도록 했다.

setTimeout은 2초 있다가 하기로 설정하고, 그 안에 들어갈 콜백함수에는 "야, 우리 이제 기능을 잘 수행했어. 우리 성공적으로 잘 해냈어!"라고 한다면 resolve라는 콜백함수를 호출하면 된다. "우리가 데이터를 받아왔는데, 사용자의 이름은 ellie였어" 라는 것이다. 성공적으로 네트워크에서 받아온 또는 파일에서 읽어온 데이터가 resolve라는 콜백함수를 통해 전달된다.

 

2) Consumer

위에서 멋진 Producer를 만들었으니, 이제 그것을 이용하는 Consumer를 만들 차례이다.

Consumer는 then, catch, finally를 이용해서 값을 받아올 수 있다.

더보기

   Consumer가 값을 받아올 수 있는 방법

  - then() : 성공했을 때

  - catch() : 실패했을 때 (Error handling)

  - finally() : 성공과 실패의 유무에 상관 없이 언제나 실행되는 부분

(1) then

const promise = new Promise((resolve, reject) =>{
    //doing some heavy work (network, read files)
    console.log('doing something...');
    setTimeout(()=>{
        resolve('ellie');
    },2000);
})
//Consumers: then
promise.then((value) => { //resolve의 결과값 'ellie'가 value로 전달됨
    console.log(value); 
})

값이 정상적으로 수행이 된다면, then(그러면), 내가 값을 받아올것이라는 의미로,

resolve의 결과 값이 then안에서 콜백함수의 파라미터로 전달이 되는 것이다. 여기에서는 resolve의 결과 값인 'ellie'가 then안의 value로 전달이 된다. 

 

그렇다면, 이 상황에서 resolve가 아니라 reject가 되었다면 어떻게 될까?

	const promise = new Promise((resolve, reject) =>{
	    //doing some heavy work (network, read files)
	    console.log('doing something...');
	    setTimeout(()=>{
	        // resolve('ellie');
	        reject(new Error('no network'));
	    },2000);
													
	})
	//2. Consumers: then, catch, finally
	promise.then((value) => {
	    console.log(value);
	})

 

위의 코드를 실행하면 이렇게 에러가 발생한다.

reject는 보통 Error라는 object를 통해서 값을 전달하게 된다. (Error는 자바스크립트에서 제공하는 오브젝트 중 하나임)
위를 실행해보면 사진처럼 error가 발생하는 것을 알 수가 있다.

Uncaught라는 것은, 우리가 then을 이용해서 성공적인 케이스만 다뤘기 때문에 Uncaught(잡히지 않은 에러)가 발생했다고 하는 것이다.

그러므로, reject되었을 때는 그 에러를 잡는(catch) 게 필요하다. 그래서 catch를 사용한다.

 

(2) catch

promise
.then((value) => {
	 console.log(value);
})                                              //then을 실행하게 되면, 또 다시 promise를 리턴하기 때문에 그것 뒤에
								catch를 또 뒤에 달 수 있는 것이다.
.catch(error => {
	 console.log(error);
})

- then을 이용해서 성공적인 경우를 잘 다뤘다면 catch를 이용해서 에러가 발생했을 때 어떻게 처리할 건지 콜백함수를 등록해주면 된다.

(3) finally

- finally는 성공과 실패에 상관 없이 무조건 실행되는 코드이다.

	promise
	.then((value) => {
	    console.log(value);
	})
	.catch(error => {
	    console.log(error);
	})
	.finally(()=> {
	        console.log('finally');
	});

 

다음 시간에는 프로미스 연결하기(Promise Chaining)에 대해서 알아보겠다.

728x90
반응형