Promise

이진경·2023년 3월 31일
0

🐤 JAVASCRIPT

목록 보기
2/9

✅ 프로미스란?

자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백함수를 사용한다.

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

💡 ES6 : 비동기 함수 호출 또는 비동기 연산이 완료되었을 때, **이후에 처리할 함수나 에러를 처리하기 위한**  함수를 설정하는 모듈

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

//Promise의 활용 예

function sendEmail(text, timeout){
	return new Promise((resolve, reject) => {
		setTimeout(()=> {
				resolve(text);
		},timeout)
	})
}

sendEmail("To. 교수님께 \n 안녕하세요.", 1000).then((text) =>
	sendEmail(`${text} oo 올림`, 1000)
).then((text) => {
	console.log(`메일 전송완료! 내용: ${text} `);
});

⁇ 프로미스가 필요한 이유

1️⃣ 탄생배경

원래는 비동기처리를 위해 콜백함수를 사용했다. 하지만 콜백함수를 사용해서 연속적으로 비동기 로직을 처리하면 콜백 지옥이 발생할 수 있다.

:: 콜백지옥의 예

setTimeout을 사용해서 3초 후에 콘솔에 아래와같은 문장을 표시하는 함수를 작성해보자.

'How are you/'
'I am fine.'
'Thank you'
'And you?'
setTimeout(() => { // 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);

위와 같은 콜백지옥은 다음과 같은 문제점들을 가지고 있다.

  • 에러 처리가 곤란하다.
  • 코드의 가독성이 떨어진다.
  • 유지보수하기 힘들다

2️⃣ 어디서 사용되는가?

프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다.

:: 프로미스 사용의 예

function getData(callbackFn){
	$.get('url 주소', function(res){
		callbackFn(res);
		});
	}

getData(function(tableData){
	console.log(tableData)
});

비동기 처리를 위해 프로미스 대신 콜백 함수를 사용한 통신 코드이다. 이 코드를 promise 를 사용해서 아래 코드처럼 변경할 수 있다.

//Promise 사용

function getData(callbackFn){
//new promise 추가
	return new Promise(function(resolve, reject){
		$.get('url 주소', function(res){
		//데이터를 받으면 resolve() 호출
		resolve(res)
		});
	});
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData){
	//resolve()의 결과 값이 여기로 전달됨
	console.log(tableData)
});

3️⃣ 프로미스의 생성

//프로미스의 생성

const promise = new Promise((resolve, reject) => {
	//프로미스 함수의 콜백 함수 내부에서 비동기 처리를 수행한다ㅣ.
	if(비동기 처리 성공){
		resolve('아싸 성공');
		} else {
		reject ('실패해쑴 ㅠㅠ');
		}
	});

Promise 생성자 함수를 new 연산자와 함께 호출하면 Promise 객체가 생성된다.

Promise 생성자 함수는 비동기 처리를 수행할 콜백함수를 인수로 전달받는데, 이 콜백 함수는 resolvereject 함수를 인수로 전달 받는다.


🧟‍♀️ 프로미스의 3가지 상태

프로미스는 다음과 같이 현재 비동기 처리가 어떻게 진행되고 있는지를 나타내는 상태 정보를 갖는다.

프로미스 상태 정보의미상태 변경 조건
pending (대기)비동기 처리가 아직 수행되지 않은 상태 ( = fulfilled도 rejected도 안된 초기 상태)프로미스가 생성된 직후 기본 상태
fulfilled (이행)비동기 처리가 수행된 상태 (성공)resolve 함수 호출
rejected (실패)비동기 처리가 수행된 상태 (실패)reject 함수 호출
💡 fullfilled 또는 rejected 상태를 settled 상태라고 한다.

1️⃣ Pending (대기)

new Promise();

new Promise() 메서드를 호출하면 Pending 상태가 된다. new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolvereject 함수를 인수로 전달 받는다.

2️⃣ Fulfilled (이행)

new Promise(function(resolve, reject) {
  resolve();
});

콜백 함수의 인자 resolve 를 실행하면 fulfilled 상태가 된다.

:: 사용 예

function getData() {
  return new Promise(function(resolve, reject) {
    let data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

3️⃣ Rejected (실패)

new Promise(function(resolve, reject) {
  reject();
});

콜백 함수의 인자 reject 를 실행하면 rejected 상태가 된다. 그리고 실패 상태가 되면 실패한 이유를 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
});

🤬 프로미스의 에러 처리

콜백 패턴은 에러 처리가 곤란하다는 문제가 있는데 프로미스는 에러를 문제없이 처리할 수 있다. 비동기 처리에 대한 후속처리는 프로미스가 제공하는 후속 처리 메서드를 사용한다.

👉 후속 처리 메서드

프로미스의 비동기 처리 상태가 변화하면 이에 따른 후속 처리를 해야 한다. 이를 위해 프로미스는 후속 메서드 then , catch , finally 를 제공한다.

then , catch 메소드는 Promise 객체를 반환하므로 chaining 형태로 사용될 수 있다.

1️⃣ then

then 메서드는 두 개의 콜백 함수를 인수로 전달받는다.

  • 첫번째 콜백 함수는 fulfilled 상태가 되면 호출
  • 두번째 콜백 함수는 rejected 상태가 되면 호출한다. )
const wrongURL = 'http ~~~ 잘못된 주소';

promiseGet(wrongURL)
.then(res => console.log(res))
.then(err => console.log(err))

2️⃣ catch

catch 메서드는 한 개의 콜백 함수를 인수로 전달받고, 프로미스가 rejected 상태인 경우에만 호출된다.

promiseGet('http ~~~ 올바른 주소')
.then(res => console.log(res))
.catch(err => console.log(err)

catch 메서드를 사용하는 것이 가독성이 좋고 명확하다.

3️⃣ finally

finally 메서드는 한 개의 콜백 함수를 인수로 전달받고, 프로미스의 fulfilled 또는 rejected와 상관없이 무조건 한 번 호출된다.

상태와 상관없이 공통적으로 수행해야 할 처리 내용이 있을 때 유용하다.

:: 에러 처리의 예

프로미스 예제 코드

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 출력
});

참고 : 캡틴판교 / 자바스크립트 딥다이브

profile
멋찐 프론트엔드 개발자가 되자!

0개의 댓글