프로미스(Promise)

Vorhandenheit ·2021년 10월 7일
0

JS/Node 

목록 보기
17/63

프로미스

콜백에 대해서 간단히 공부하고 난 후에는 이제는 프로미스에 대해서 배울 차례입니다. 프로미스는 콜백함수가 계속해서 연결되는 경우, 코드도 보기 힘들어지고 계속 물고 늘어지기 떄문에 에러가 발생할 가능성이 높아지는데 이에 대한 해결책으로 나온 것입니다.

function increase (n, callback) {
	setTimeout(() => {
    	const increased = n + 1;
      	console.log(increased);
      	if (callback) { // 콜백함수가 있다면
        	callback(increased); //매개변수에 n+1을 넣어라
        }
    }, 1000); //1초 뒤에 실행
}

increase(0, n => {
	increase(n, n => {
    	increase(n, n => {
        	increase(n, n=> {
            })
        })
    })
})

이런 식으로 콜백함수에 또 콜백함수를 넣고 또 넣고 해서, 차례대로 1씩 더하면서 출력할 것입니다.

1.Promise

프로미스를 쓰는 이유는 결국 가시성을 좋게하여 코드의 유지 보수를 좀 더 효율적이게 하기 위함입니다.

1) Promise 문법

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

or

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

프로미스 객체는 인스턴스 생성처럼 new 키워드와 생성자를 통해 객체를 생성합니다. 그리고 두개의 함수를 인자로 받습니다.(resolve, reject)

2) Promise 상태 state

위의 그림에 보면 state: 에 3가지 상태가 있습니다. 각각 Pending(대기), Fulfilled(이행), Rejected(실패)를 나타냅니다. 이러한 상태를 두면 조건문 처럼 성공했을 때 실패했을 때 각각 분리해서 처리할 수 있습니다.

  • Pending(대기) : promise 객체를 생성하였고, 아직 성공이나 실패와 같은 처리 결과가 이루어지지 않은 진행 전 상태를 나타낸다.
function devide(numA, numB) {
	return new Promise((resolve, reject) => {
    	if (numB === 0) {
        	reject(new Error("fail"));
        }
      	else {
        	setTimeout(() => reslove(numA / numB), 1000))
        }
    });
}

아직 생성자를 만들어 매개변수를 넣기 전이기 때문에 devide의 상태는 pending(대기) 상태입니다.

  • Fulfilled(이행) : resolve 를 수행하게 되면 promise 객체는 fufilled 상태가 됨, 이행 상태가 되면 then()을 이용해 처리 결과를 받아올 수 있습니다.
devide(4, 2)
	.then((result) => console.log("성공", result))
	.catch((error) => console.log("실패", error));

4가 2로 나누어져서 resolve가 1초뒤에 실행되었고 매개변수가 then으로 받아와서 출력함을 볼 수 있습니다.

  • Rejected(실패) : 처리가 실패되면 reject()를 수행하여 Rejected 상태가 되며, catch()를 이용해 결과값을 받아 올 수 있다.
devide(8, 0)
	.then((result) => console.log("성공", result));
	.catch((error) => console.log("실패", error));

numB가 0이기 떄문에 catch() 메서드가 호출되었고 fail을 반환하고 "실패"를 출력합니다.

3)then, catch 메서드

  • then
    프로미스가 종료되면 resolve에 들어간 값을 받을 수 있습니다.
promise.then(
	function(result) {} // 첫 번쨰 인수는 프라미스가 이행되었을 떄 실행되는 함수, 실행 결과를 받음 
  	function(error) {} // 두 번쨰 인수는 프라미스가 거부되었을 때 실행되는 함수, 에러를 받음
)
  • catch
    catch(n) 는 then(null, n)과 같습니다.
    에러가 발생했을 경우 reject 실패상태가 된 이유를 받습니다.
    then에서도 에러처리를 받을 수있는데 , 왜 catch를 쓰냐면 명시적으로 구분하기 위해서입니다. 또 프로미스 체이닝에서

2. 프로미스 체이닝

상황에 따라 promise를 여러 번 사용해야하는 경우가 존재합니다.

new Promise(function (resolve, reject) {
	setTimeout( () => resolve(1), 1000);
}).then(function(result) {
	return result * 2
}).then(function (result) {
	return result *2
}).then(function (result) {
	return result *2
})

반환 값이 넘어가면서 최종적으로는 8이 반환됨

then 메서드 내에서 직접 promise를 return 도 가능

cook()
.then(function() {
	return readytofood()
})
.then(function() {
	return cookFood
})
.then(function() {
	return settingFood
})

연속적으로 사용하여 순차적인 작업도 할 수 있음

예외 (에러) 처리

마지막 catch 구문에서 모든 에러를 한번에 처리가 가능

goToSchool() .then(function(){ return arriveAtSchool(); }) .then(function(){ return studyHard(); }) .then(function(){ return eatLunch(); }) .catch(function(){ leaveEarly(); });

출처: https://sangminem.tistory.com/284 [미리 알았다면 좋았을 텐데]

3.프라미스 메서드

promise 클래스에는 5가지 정적 메서드가 있습니다.

1) Promise.all

  • promise.all은 요소 전체가 프라미스인 배열을 받고, 새로운 프라미스를 반환
  • 배열 안 프라미스가 모두 처리되면 새로운 프라미스가 이행, 배열 안 프라미스의 결과값을 담은 배열이 새로운 피라미스 result가 됨
  • 첫 번쨰 프라미스는 가장 늦게 이행되더라도 처리결과는 배열의 첫 번째 요소에 저장
  • 전달되는 프라미스 중 하나라도 거부되면, promise.all이 반환하는 프라미스는 에러와 함께 거부됨
Promise.all([
	new Promise(resolve => setTimeout(() => resolve(1), 3000)),
  	new Promise(resolve => setTimeout(() => resolve(2), 2000)),
  	new Promise(resolve => setTimeout(() => resolve(3), 1000))
]).then(alert);

에러가 있는 경우 allPromise에 대해서 해주면 됨

const p1 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, "First reject");
})

const p2 = new Promise(resolve => {
  setTimeout(resolve, 1000, "Second");
})

const p3 = new Promise(resolve => {
  setTimeout(resolve, 3000, "Third");
})

const allPromise = Promise.all([p1,p2,p3]);
allPromise
.then(values => console.log(values))
.catch(error => console.log(error));
// First reject

2) Promise.race

가장 먼저 처리되는 프라미스의 결과를 반환

Promise.race([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert); // 1
profile
읽고 기록하고 고민하고 사용하고 개발하자!

0개의 댓글