Promise

jini.choi·2022년 5월 17일
0
  • 비동기 작업을 좀 더 편하게 처리 할 수 있도록 ES6에 도입된 기능

  • 예전에 비동기 작업을 할 때 어떤 작업이 끝나고 나서 뭘 해야한다 했을 때 callback함수로 처리를 해줬어야 했는데, callback함수로 처리시 비동기 작업이 많아질 경우 코드가 쉽게 난잡해졌다.

  • 그래서 promise라는게 만들어졌다. 원래는 라이브러리로 존재 했지만, 편하다 보니 일반 JS스펙에 추가된 기능

  • 비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 promise를 사용하여 결과를 반환. 그러나 비동기 함수를 사용하는 코드의 구문과 구조는, 표준 동기 함수를 사용하는 것과 많이 비슷하다.

  • 즉, promiseresolvereject, .then()을 우리가 익숙산 동기 함수를 작성하는 것처럼 만들어주기 위해 추가된 문법이라 생각하면 된다.

  • 이 과정에서 평상시 사용하던 것처럼 try catch문을 사용할 수 있는 것, 그렇지만 이렇게 만들어진 async function도 promise를 반환하므로, promise를 이용해 만든 함수처럼 사용할 수 있다.

callback함수를 사용 시(callback 지옥)

function increaseAndPrint(n, callback){
	setTimeout(() => {
		const increased = n + 1;
		console.log(increased);
		if(callback){
			callback(increased)
		}
	}, 1000)
}

increaseAndPrint(0, n => {
	increaseAndPrint(n, n => {
		increaseAndPrint(n, n => {
			increaseAndPrint(n, n => 
				increaseAndPrint(n, n => {
					console.log('작업 끝!');		
				})
			)
		})
	})
});

동작의 흐름

  • 초반의 increaseAndPrint함수에선 첫번째 파라미터 n에 숫자를 받아오고 두번째 파라미터에선 n에 1을 던한 결과 값을 인자로 넣어서 호출 할 함수를 받아온다.
  • increaseAndPrint가 호출되고 나서 또 다시 자기 자신을 호출하기 위해 연달아서 increaseAndPrint가 작성 됐다.
  • 해당 코드에서는 <increaseAndPrint호출 -> n1더함 -> 더한 값을 가지고 다시 increaseAndPrint호출>이 값이 5가 될때까지 반복

promise함수를 사용 시

  • promise는 성공할 수 있고, 실패할 수도 있다. 성공 할 때는 resolve, 실패할 때는 reject호출
  • .then으로 promise가 끝나고 할 작업을 설정
  • resolve 와 reject가 왜 나왔는가
  • promise를 만들때는 resolve와 reject를 파라미터로 받아오는 함수를 인자로 넣어줘야 함

성공시(resolve)

const myPromise = new Promise((resolve, reject) => {
	//구현...
	setTimeout(() => {
		resolve('result');
	}, 1000)
});

myPromise.then(result => {
	console.log(result);
});

실패시 - 에러를 잡을땐 .catch

const myPromise = new Promise((resolve, reject) => {
	//구현...
	setTimeout(() => {
		reject(new Error());
	}, 1000);
});

myPromise.then(result => {
	console.log(result)
}).catch(e => {
	console.error(e);
})
  • catch, console.error

- promise의 catch 함수는 앞서 만든 promise에서 reject한 값을 받아 올때 사용한다.
여기서 e는 reject에 인자로 넣어준 값이다.

- console.error 는 console.log와 달리 빨간색으로 나온다. 콘솔에서 에러가 난 것을 더욱 쉽게 알 수 있게 해준다.


promise를 만드는 함수

function increaseAndPrint(n){
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const value = n + 1;
			if(value === 5) {
				const error = new Error;
				error.name = 'ValueIsFiveError';
				reject(error);
				return;
			}
			console.log(value);
			resolve(value);
		}, 1000);
	});
}

increaseAndPrint(0).then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e => {
	console.error(e);
})
  • increaseAndPrint의 파라미터에 콜백이 사라진 이유
    - 콜백을 없앤 이유는 우리가 콜백을 통해서 그 다음 처리 할 작업을 넣어주지 않고 promisethen을 통해서 하기 위함

  • error를 따로 만든 이유
    - errorValueIsFiveError라는 이름을 설정 해주기 위함
    - n + 1값은 promise의 결과값으로 n + 1를 설정한다는 뜻

  • then
    - increaseAndPrint(0) 의 결과 1을 .then의 파라미터 n으로 받아와서 다시 increaseAndPrint 를 호출

  • catch 왜 했는지
    - catch를 한 이유는 에러가 발생했을 때 특정 작업을 하기 위함
    - catch를 안했을 땐 "Uncaught (in promise) ValueIsFiveError" - ValueIsFiveError 가 잡히지 않았다.
    - catch를 했을 땐 ValueIsFiveError 라고 나타남
    - 즉, 콘솔에 출력되는 결과가 다르기 때문

  • 함수를 넣어주기
    - .then에 인자로 넣어주어야 하는 것은 함수다.
    - .then에서 새로 함수를 선언하지 않고 increaseAndPrint 를 넣어주면 앞서 호출한 increaseAndPrint 의 결과값을 다시 increaseAndPrint 의 인자로 넣어서 호출하게 된다.
    - 파라미터를 여러개 받아와야 하는 경우에는 함수를 새로 선언해야 한다.


  • node에서 왜 오류가 나는지
    - node에서 promise에서 발생한 에러를 .catch 하지 않으면 UnhandledPromiseRejectionWarning이라는 경고 메세지가 뜸. 브라우저에서는 Uncaught (in promise) ValueIsFiveError 라는 오류가 뜸

이 글은 패스트캠퍼스 '프론트엔드(React)올인원패키지Online'을 수강하며 정리한 노트입니다.
https://fastcampus.co.kr/search?keyword=%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C

profile
개발짜🏃‍♀️

0개의 댓글