[JavaScript] Promise

DongHwan·2021년 5월 24일
0

nodejs

목록 보기
9/11
post-custom-banner

Single-Thread기반의 자바스크립트에서는 비동기 처리를 위해 콜백(CallBack)을 사용해왔다. 어떤 작업을 요청하면서 콜백 함수를 등록하면, 작업이 수행된 후 결과를 콜백 함수를 통해 전달하는 방식이다. 이 콜백은 비동기 처리를 하는데 유용하지만, 비동기 처리를 순차적으로 실행할 필요가 있는 경우 콜백을 중첩해 사용함으로써 복잡도가 높아지게 된다. 복잡도가 높아짐으로써 유지/보수가 어려워지고, 예외 및 에러 처리 역시 힘들어진다. 이런 경우를 해결하고자 Promise 패턴이 제안되었다.

Promise가 나오게 된 배경에서 알 수 있듯이, Promise 역시 어떠한 작업을 비동기로 처리한 이후 결과값을 처리하기 위해 사용한다.

Promise 생성

const myFunc = (isDone) => {
 return new Promise((resolve, reject) => {
   if (isDone){
     resolve("완료");
   }
   else{
     reject("실패");
   }
}

특정 함수를 사용한 후, Promise를 사용하려면 Promise 객체를 새로 만들어 반환하면 된다. 또한, Promise 객체를 생성할 때는 인자 두개를 가지는 함수를 전달해주어야 한다.

resolve와 reject에 대해 설명하기 전에 Promise의 상태에 대해 알아보자. Promise는 다음과 같은 3가지 상태를 가진다.

  • Pending(대기) : 비동기 처리가 완료되지 않은 상태
  • Fulfilled(이행) : 비동기 처리가 완료되어 Promise가 결과 값을 반환한 상태
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

resolve를 호출하면, Promise는 Fulfilled 상태가 되고 resolve의 인자 값을 넘기게 된다.
reject를 호출하면, Promise는 Rejected 상태가 되고 reject의 인자 값을 넘기게 된다.

Promise 실행

const myFunc = (isDone) => {
  //...
}

myFunc(true).then((data) => {console.log(data)}).catch((err) => {console.log(err)});

myFunc(false)
.then((data) => {console.log(data)})
.catch((err) => {console.log(err)});
// 결과
완료
실패

반환 받은 Promise 객체는 then()catch()를 통해 사용이 가능한데, then()은 Promise가 Fulfilled 상태일 때, catch()는 Promise가 Rejected 상태일 때 실행이 된다.
각 함수의 인자(data, err)로는 각각 Promise를 생성에서 resolvereject를 호출할 때 넣은 값이 들어간다.

Promise Chaining

Promise.then() 혹은 Promise.catch()를 호출하면 Promise 객체가 반환이 된다. 즉, Promise.then을 호출한 다음에 다시 Promise.then을 호출하거나 Promise.catch를 사용할 수 있다. 또한, 해당 핸들러에서 반환한 값이 다음 핸들러의 인자값이 된다.

아래는 그 예시 코드이다.

new Promise((resolve, reject) => {
  resolve(1);
})
.then((result) => {
  console.log(result);
  return result * 2;
})
.then((result) => {
  console.log(result);
  return result * 2;
})
.then((result) => {
  console.log(result);
  return result * 2;
})
// 결과
1
2
4

Promise.all

여러 개의 Promise가 모두 완료되었을 때, 특정 동작을 실행하고 싶다면 Promise.all()을 사용하면 된다. Promise.all()은 파라미터로 갖는 모든 프로미스가 완료되면 다음 동작이 수행된다.

const p1 = new Promise((resolve, reject) => {
  resolve("p1");
});
const p2 = new Promise((resolve, reject) => {
  resolve("p2");
});

Promise.all([p1, p2])
	.then((values) => {console.log(values)});
// 결과 
[p1, p2]
profile
날 어떻게 한줄로 소개해~
post-custom-banner

0개의 댓글