Promise 와 async/await

람다·2021년 6월 25일
0

JS

목록 보기
2/3
post-thumbnail

프로미스는 JS 비동기 처리에 사용되는 객체이다. 여기서 비동기 처리란 저번 글에서 설명했던 것처럼 ‘요청을 보낸 후 응답과 관계없이 다음 동작을 실행하는 방식’이다.

Promise는 왜 필요할까?

프로미스는 보통 서버에서 받아온 데이터를 화면에 표시할 때 사용한다. 일반적으로 웹앱을 구현할 때 서버에서 데이터를
요청하고 받아오기 위해 실행한다.

마치 매장에서 커피를 주문했을 때 번호표를 받고 해당 순서가 되면 커피를 받으러 가는 것과 같다.

프로미스의 3가지 상태

프로미스를 사용할 때 알아야 하는 기본 개념은 프로미스의 상태(state)이다. 여기서 말하는 상태는 프로미스의 처리 과정을 의미한다. new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 가진다.

Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
Fulfilled(이행=완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

Pending(대기)

먼저 new Promise() 메서드를 호출하면 대기 상태가 된다.

 new Promise();

new promise에 전달되는 함수는 executor (실행자, 실행 함수) 라고 부른다.
new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수 인자는 resolve, reject이다.
executor에선 상황에 따라 인수로 넘겨준 콜백 중 하나를 반드시 호출해야 한다.

new Promise(( resolve, reject )=>{
	// resolve(value)  fulfilled
	// or
	// reject(“error”) rejected

});

Resolve(value) - 일이 성공적으로 끝난 경우, 그 결과를 나타내는 value와 함께 호출
reject(error) - 에러 발생 시 에러 객체를 나타내는 error와 함께 호출

Fulfilled(이행 = 완료)

여기서 콜백 함수의 인자 resolve를 아래처럼 실행하면 이행(Fulfilled) 상태가 된다.
이행 상태가 되었을 때 then()을 이용하여 처리 결과 값을 받을 수 있다.

const getEgg =() => {
	return new Promise((resolve, reject) => {
	let egg = 30;
	resolve(egg);
});
}

//resolve()의 결과 값 egg의 갯수를 resolveEgg로 받음
getEgg().then((resolveEgg) => {
	console.log(resolveEgg); //30

}) ;

Rejected (실패)

new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있다고 했는데, 여기서 reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.

const getEgg = () => {
	return new Promise((resolve, reject) =>{
	reject(new Error(“not Egg”));
});
}

getEgg().then().catch((err)=> {
	console.log(err);
});

Promise의 핵심

프로미스의 장점은 비동기 처리시 발생하는 콜백 헬을 해결하는 것도 있지만 중요한 포인트 2가지가 있다.

return value를 이용할 수 있다

비동기 처리에서는 return 값은 아무런 의미를 갖지 않는다. 함수 실행문 안에서 또 다른 함수가 실행되고 또 다른 함수가 실행되는 방식이기 때문이다. 그래서 return된 값으로 다룰 틈도 없이, 비동기 처리가 이루어진다.

하지만 프로미스를 이용할 경우, return값을 가지고 있는 프로미스 객체를 가질 수 있기 때문에 동기 코드처럼 그 값에 변수를 할당하거나, 다양한 메소드를 사용할 수 있어 자유롭게 작업이 가능하다.

Error handling이 동기식 코드와 유사하게 쓰일 수 있다

비동기 처리에서 모든 콜백함수에 각각 에러 핸들링을 해줘야 했지만, 프로미스를 이용할 경우 then, catch등을 통해 에러에 대한 대처가 간결해졌다.

그러므로 프로미스의 포인트는 비동기 흐름을 동기적 흐름과 유사하게 만들어주었다는 것이다.

Async/await

프로미스와 같이 비동기 모드를 작성하는 새로운 방법이며 동기적으로 처리할 수 있게 한다.
프로미스보다 코드가 간결해지고, 가독성이 높아지는 장점이 있다.

//promise 
const getEgg= () => {
	return new Promise((resolve, reject)=>{
	  const egg = 5;
	resolve(egg)
	});
}

// async/await 
async result = () => {
	const resultEgg = await getEgg();
	console.log(resultEgg); // 5
}

result(); // 5 

Async

Async 함수를 실행하게 되면 프로미스 객체가 반환된다.
그러므로 async함수 내에서 return은 반환된 Promise 객체의 결과(resolve)값이다.

 async egg = () => {
	return 5
}

const f = egg(); // 변수 f에 프로미스 객체가 할당된다.
console.log(f) // promise { <fulfilled> : 5 }

await

await 는 반드시 async 안에서만 사용할 수 있고, 일반 함수에서 사용하면 에러를 발생시킨다.

JS가 await를 만나게 될 때 해당 함수가 프로미스 상태가 이행될 때까지 기다렸다가, 이행이 완료되면 그 결과 값을 반환하고 다음 코드를 실행한다.

await를 사용하면 기존의 실행 순서가 예측이 불가능했던 비동기 작동 방식이 동기적으로 실행되는 코드처럼 예측 가능해질 수 있다는 장점이 있다.

https://blog.domenic.me/youre-missing-the-point-of-promises/

profile
오늘의 람다

0개의 댓글