강민승 2022. 12. 8. 03:13

promise 정의

프로미스는 자바스크립트에서 비동기처리를 간편하게 도와주는 객체이다.

정해진 장시간의 기능을 수행하고난 후 정상적으로 기능이 수행된다면 메시지를 전달함과 동시에 결과값을 전달하고 

예상하지 못한 결과가 나왔을 때 에러를 전달한다.

 

const promise = new Promise();

 

Promise는 두가지의 콜백함수를 받는다. 

 

resolve reject
기능을 정상적으로 수행해서 마지막에 최종 데이터를 전달 기능을 전달하다가 중간에 문제가 생기면 보냄

 

Promise 에는 3가지 상태가 있다.

  • Pending (대기)
  • Fulfilled (이행)
  • Rejected (실패)

비동기 처리가 완료 되지 않았다면 Pending, 완료 되었다면 Fulfilled, 실패하거나 오류가 발생하였다면 Rejected 상태를 갖는다.

 

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

    console.log(‘let’s go’);

    setTimeout(()=>{
       resolve(‘hello world’);
       reject(new Error(‘no! ’));
    },3000);

});

 

프로미스 안에 네트워크 통신을 하는 코드를 작성했다면 프로미스가 만들어지는 순간 네트워크 통신을 수행하게 된다.

 

여기서 중요한 포인트 

네트워크 요청을 사용자가 요구했을때만 사용해야한다면 이런식이라면 요구도 하지않았을때 불필요한 통신을 할 수 있다.

(새로운 프로미스가 만들어질때는 전달한 excutor가 바로 실행된다.)

 

 

Promise 사용하기(then, catch, finally)

 

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

    console.log(‘let’s go’);

    setTimeout(()=>{
       reject(new Error(‘no! ’));
    },3000);

});



promise.then((value) =>{

     console.log(value) 

     // let’s go



})

.catch(error => {

    console.log(error); // no!

})

.finally(()=>{

   console.log(‘finally’);

});

 

만약 prosmise가 잘 전달이된다면 resolve의 값이 then에 있는 value의 파라미터에 잘 전달 되는 것을 볼 수 있다.

 

만약 전달이 되지 않는다면 catch문에서 console.log가 실행된다. 

 

전반적인 과정은 promise를 생성한 후 then을 호출하게 되면 다시 promise를 호출하게 되고 리턴된 프로미스에 catch를 등록하는것이다. 이렇게 연결하는 방식을 체이닝이라고 한다.

 

최근에 추가된 문법 finally();

성공하던 실패하던 마지막에 호출되는 메소드.

성공여부와는 상관없이 마지막에 어떤 기능을 실행하고 싶을 때 finally를 사용할 수 있다

 

 

const dataNumber = new Promise((resolve,reject) => {

setTimeout(()=>{

         resolve(1), 2000)

   })

})



dataNumber

.then(num => num * 4)

.then(num => num * 2 )

.then(num => {

return new Promise((resolve,reject) =>{
           setTimeout(()=>{ resolve(num -1) }, 1000)

        })

})

.then(num => console.log(num));

 

then은 값을 반환할 수도, promise를 반환할 수도 있다.  예를 들어 then에 전달된 함수가 promise를 반환할 경우 이와 동등한 프로미스가 메서드 체인의 다음 then에 노출된다.

 

 

Promise 와 async/await

 

Javascript의 동기식 흐름을 따르지 않는 비동기 처리의 특성상, 비동기 작업의 실행 순서가 보장되지 않는다.

그리하여 콜백함수가 등장하게 되었는데, 순서대로 실행하려는 파일의 개수가 늘어날수록 가독성이 안좋게 되어버린다는 점이 문제가 되었다. 이 외에도 예외처리를 위해 콜백함수마다  try...catch 문법을 사용해야 해서 번거로움이 단점으로 꼽히기도 했다.

Promise callback 패턴의 여러 단점을 보완하기 위해서 생긴 기능이다.

Promise 의 경우 비동기 처리를 실행하긴 하지만, 결과를 바로 callback 함수로 건네주는 것이 아니라 나중에 처리할 수 있다는 것이 특징이다.

하지만 Promise 객체 또한  .then()과같이 꼬리에 꼬리를 무는 코드가 나올 수도 있다는 부분이 단점으로 꼽힌다. 

Promise와 콜백함수의 단점을 해소하고자 async/await가 만들어졌다.

 

Promise와 async/await의 차이점으로는 에러핸들링을 예로 들 수 있다. 

 

Promise의경우 .catch()문으로 에러들을 처리할 수 있지만 async/await의 경우 별도의 에러처리 기능이 없기 때문에 try-catch문을 사용하여야 한다.

또한 Promise의 경우 콜백지옥으로 인해 코드가 번잡해 보일 수 있지만 async/await는 비동기처리코드가 동기코드처럼 보여 코드의 흐름을 이해하기 쉽다.

 

 async function showAvatar() {
  // JSON 읽기
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // github 사용자 정보 읽기
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();
 
 }