새소식

ECMAScript

ECMAScript (ES6) Promise

  • -

Promise는 콜백지옥 현상을 해결하기 위해 등장한 패턴입니다!

Promise가 나오기 전까지는 콜백이 중첩될 때마다 복잡해지고 가독성을 해지는 일이 많아져서 콜백지옥에 빠지는 현상이 많았습니다. 

이런 문제를 해결하고 또 비동기 작업을 조금 더 편하게 처리할 수 있도록 도입되었습니다. 

 

기존 비동기 처리(콜백 지옥) 

파라미터로 n을 받아 setTimeout으로 5번에 걸쳐 1초마다 1씩 더하여 출력하는 코드입니다. 

코드의 깊이가 너무 깊어 가독성이 좋지 않고 복잡합니다. 

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('끝!');
        });
      });
    });
  });
});

 

Promise 비동기 처리

Promise를 사용하면 비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않게 된다. 

function increaseAndPrint(n) {
  return new Promise((resolve, reject)=>{
    setTimeout(() => {
      const increased = n + 1;
      console.log(increased);
      resolve(increased);
    }, 1000)
  })
}
 
increaseAndPrint(0)
  .then((n) => increaseAndPrint(n))
  .then((n) => increaseAndPrint(n))
  .then((n) => increaseAndPrint(n))
  .then((n) => increaseAndPrint(n)); // 체이닝 기법

Promise                                                                                                                                     

Promise는 비동기 작업이 완료된 이후에 다음 작업을 연결시켜 진행할 수 있습니다. 

 

const promise = new Promise((resolve, reject) => {
  try {
    ...비동기 작업
    resolve(결과);
  } catch (err) {
    reject(err);
  }
});

Promise는 위와 같이 만들 수 있습니다. 

작업결과에 따라 성공 또는 실패를 리턴하면 결과 값을 전달 받습니다. 

성공하면 resolve를 호출해주고, 실패하면 reject를 호출해줍니다. 

 Promise의 객체는 

 

promise.then((result) => {
  // result 처리
}).catch((err) => {
  console.error(err);
});

여기서 then과 catch로 받습니다. resolve의 결과 값은 then의 result로 , reject의 err은 catch의 err로 갑니다. 

 

예시

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

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

1초 뒤에 성공시키는 상황에 대해 구현한 코드인데

resolve를 호출할 때 특정 값 (여기서는 1)을 파라미터로 넣어주면 이 작업이 끝나고 사용할 수 있습니다. 

다음 작업을 할 때에는 .then()을 사용하고 then의 콜백함수의 인자로 1을 받을 수 있습니다. 

 

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((n) => {
  console.log('result: ', n);
})

 

 


Promise의 단점 

 

  • 에러를 잡을 때 몇번째에서 발생했는지 알아내기 어렵다.
  • 특정 조건에 따라 분기를 나누기 어렵다.
  • 특정 값을 공유해가면서 작업을 처리하기 어렵다. 

 

 

참고자료 :https://velog.io/@ljinsk3/JavaScript-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-Promise-%EA%B0%9D%EC%B2%B4 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.