Promise

송민준·2024년 8월 27일

프론트엔드

목록 보기
1/2

콜백지옥

프론트엔드 개발을 하며 생각보다 많이 비동기 처리를 해야 했고 이전에는 끼워맞추는 식으로 콜백 함수를 집어넣었다. 그러다 아래와 같이 A 작업이 끝나면 B 작업, B 작업이 끝나면 C 작업. 이런 식의 연쇄적인 작업을 구현하기 위해 콜백을 막무가내로 사용하는 콜백 지옥을 경험했다.

const calculate = (callBack: (result: number) => void) => {
  const addend = 3;
  setTimeout(() => callBack(addend), 1000);
};
const callBack1 = (augend: number, callBack: (result: number) => void) => {
  const addend = 2;
  setTimeout(() => callBack(augend + addend), 1000);
};
const callBack2 = (augend: number, callBack: (result: number) => void) => {
  const addend = 1;
  setTimeout(() => callBack(augend + addend), 1000);
};

calculate((result: number) => {
  callBack1(result, (result: number) => {
    callBack2(result, (result: number) => {
      console.log("end of callback : " + result);
    });
  });
});

프로미스

프로미스는 비동기 작업의 미래 완료 또는 실패를 나타낸다.

  • 프로미스 생성: 프로미스 객체를 생성할 시점에 즉시 전달된 메서드가 실행된다.
new Promise((resolve, reject) => {
  ...
  resolve();
  ...
});
  • .then: 성공했을 때 실행되는 resolve 정의
  • .catch: 실패했을 때 실행되는 reject 정의

장점

  • 미래 작업에 대한 메서드를 프로미스를 통해 정의하기 때문에 비동기 메서드를 마치 동기 메서드처럼 처리할 수 있다.
    - ex: doSomething().then((value) => doSomething1(value).then(...
  • chaining으로 가독성을 높일 수 있다.

Chaining을 통한 콜백지옥 해결

위에 콜백지옥을 다뤘는데 프로미스는 이를 Chaining을 통해 해결한다.
Chaining이 가능한 이유는 프로미스의 then에서 프로미스를 넘겨줄 수 있기 때문이다.

const calculate = (): Promise<number> => {
  const addend = 3;
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(addend);
    }, 1000);
  });
};
const callBack1 = (augend: number): Promise<number> => {
  const addend = 2;
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(augend + addend);
    }, 1000);
  });
};
const callBack2 = (augend: number): Promise<number> => {
  const addend = 1;
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(augend + addend);
    }, 1000);
  });
};
calculate()
  .then(callBack1)
  .then(callBack2)
  .then((result) => console.log(result));

에러 핸들링

그리고 에러 핸들링에 관해서도 간단해졌다. 이전 콜백지옥에서는 모든 비동기처리 함수에 에러 함수를 중복해서 넣었다면 프로미스에서는 catch로 에러를 핸들링 할 수 있다.

...
calculate()
  .then(callBack1)
  .then(callBack2)
  .then((result) => console.log(result))
  .catch(failureCallback);

finally

비동기 작업이 성공적으로 마치던 실패로 끝나던 끝으로 실행하는 메서드를 정의한다.
connection을 종료시켜야하는 상황에서 사용할 수 있을 것 같다.

calculate()
  .then(callBack1)
  .catch(failureCallback);
  .finally(() => console.log("The End"));

Reference

profile
개발자

0개의 댓글