JavaScript

[JS] Promise란 무엇인가?

Leo(상원) 2023. 3. 20. 22:44
반응형

프로미스(Promise)

자바스크립트는 비동기를 처리하기 위해서 콜백함수를 사용합니다. 하지만 콜백을 너무 많이 사용하게 되면 개발자라면 흔히들 들어본 콜백지옥을 겪게 됩니다. 에러처리도 불편하고 비동기를 한 번에 처리를 하는데 한계가 있습니다.

 

콜백지옥

위의 짤을 콜백지옥의 유명한 짤입니다. 이미지 처럼 콜백의 무한한 중첩으로 코드의 맥락과 흐름을 파악하기 어렵고 코드의 뎁스가 굉장히 깊어져서 개발자들의 가독성을 떨어뜨리는 안 좋은 행위입니다. 하지만 이러한 콜백 함수의 단점을 보완하며 비동기 처리에 사용되는 객체를 프로미스(Promise)라 합니다.

 

프로미스는 비동기 동작을 처리하기 위해 (ES6)부터 도입된 Javascript의 내장 클래스입니다.

 

프로미스(Promise)의 장점

  • 비동기 처리 시점을 명확하게 표현할 수 있다.
  • 연속된 비동기 처리 작업을 수정, 삭제, 추가하기 편하고 유연하다.
  • 비동기 작업 상태를 쉽게 확인할 수 있다.
  • 코드의 유지 보수성이 증가한다.

Promise는 4가지의 상태를 가지고 있습니다.

  1. fulfilled: Promise가 성공했을 때
  2. rejected: Promise가 실패했을 때
  3. pending: 아직 보류중일 때 ( fulfilled나 rejected가 나기 전 )
  4. settled: fulfiied나 rejected 상태가 나온 후

Javascript에서 Promise를 만들어 봅시다.

const promise = new Promise((resolve, reject) => {
// ..생략
})

 

매개변수로 resolve와 reject 두개의 매개변수를 받습니다. 만약 콜백 함수의 기능을 수행하고 결과가 성공적이면 resolve를 호출합니다. 반대로 결과가 실패했다면 reject를 호출합니다.

 

이제 완벽한 사용법을 익혀봅시다.

const promise = new Promise((resolve, reject) => {
  let a = 1 + 1
  
  if (a==2) {
    resolve('success')
  } else {
    reject('failed')
  }
})

promise.then((res) => {
  console.log(res)
}).catch((res) => {
  console.log(res)
})

 

후속 처리 메소드

프로미스로 구현된 비동기 함수를 호출하는 측에서는 프로미스 객체의 후속 처리 메서드(then, catch)를 통해 비동기 처리 결과 또는 에러 메시지를 전달받아 처리합니다.

 

then

  • then 메서드는 두 개의 콜백 함수를 인자로 전달받습니다.
  • 첫 번째 콜백 함수는 성공(fulfilled, resolve 함수가 호출된 경우) 시에 실행됩니다.
  • 두 번째 콜백 함수는 실패(rejected, reject 함수가 호출된 경우)시에 실행됩니다.
  • then 메서드는 기본적으로 프로미스를 반환합니다.

catch

  • catch 메소드는 비동기 처리 혹은 then 메소드 실행 중 발생한 에러(예외)가 발생하면 호출됩니다.
  • catch 메소드 역시 프로미스를 반환합니다.

Promise.all

Promise.all 메소드는 정말 유용한 메서드입니다. 프로미스가 담겨있는 배열과 같은 이터러블 객체를 인자로 받습니다.

인자로 전달받은 모든 프로미스를 병렬로 처리하고 그 결괏값을 배열에 담아 resolve로 반환합니다.

 

한 컴포넌트 내에서 많은 Promise를 한 번에 순차적으로 처리해야 할 때 보일러 플레이트도 많이 줄이면서 순서를 보장받게 실행시킬 때 굉장히 유용합니다.

Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 1000)),
  new Promise(resolve => setTimeout(() => resolve(2), 2000)),
  new Promise(resolve => setTimeout(() => resolve(3), 3000)),
]).then(console.log)
.catch(console.log)

 

마지막 정리

Promise는 이벤트의 비동기 처리가 필요할 때 사용되고, 비동기 http 요청을 처리할 때도 사용할 수 있습니다.

 

 

반응형