본문 바로가기

취업/면접

Promise 면접질문

반응형

면접질문으로 맨날 듣는 단골 질문들이 있따. 근데 나는 제대로 답을 하지 못한다.. 왜일까? 왜긴 제대로 정리를 안해서다. 그래서 질문들을 정리할 까 싶은데 지금 생각나는 거는

 

  1. Promise
  2. Prototype
  3. Was vs Webserver
  4. 불변성
  5. 순수함수
  6. nextjs

정도가 있따.

 

일단 오늘은 promise에 대해서 정리해보자.

 

면접관님은 물어볼것이다.

 

Q : Javascript에서 Promise가 무엇일까요?

 

A(22.02 현재의나) : Promise는 js 콜백 형태를 보완하기 위해 나온 비동기 통신 방식입니다. js에서 콜백헬의 문제인 상황에서 이를 해결

하기 위해 이런 패턴이 나왔고 상태로는 resolve, pending, reject를 가지며 return은 resolve나 reject로 받습니다.

 

현재의 나는 위처럼 틀리지는 않지만 명확히 설명하지 못하고 횡설수설할 것이다. 나는 이게 싫으니 명확하게 정리하고 넘어가고 싶다.

Promise란?

일단 promise란 무엇인가?에 대해서 본질적인 접근을 해보자.

 

promise는 js에서 비동기를 처리하기 위한 패턴이다. 기존에 전통적인 콜백 패턴이 가진 단점을 보완하여 비동기 처리 시점을 명확히 표현할 수 있다는 장점을 가지고 있다.

 

그렇다면 기존에 가지고 있는 전통적인 콜백 패턴의 단점에 대해서 알아보자.

비동기 처리 시점이 명확하게 표현할 수 없다는 점을 확인하고 싶은데

 

비동기 통신은 말 그대로 비동기로, 즉 병렬로 요청을 처리한다. 그러다 보니 처리 순서를 보장하기가 어려운데 이를 해결하기 위해 네스팅 즉 중첩을 이용한다. 중첩을 처리하는 과정에서 복잡도가 높아지면 콜백 헬이 발생한다. 콜백 헬은 가독성을 나쁘게 하며 코딩을 복잡하게 한다.

// 예시

step1(function(value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        step5(value4, function(value5) {
            // value5를 사용하는 처리
        });
      });
    });
  });
});

비동기 모델은 실행 완료를 기다리지 않고 바로 다음 테스크를 처리하기 때문에 원하는 동작이 발생하지 않을 수 있다. 이를 위해, 순서를 보장하기 위해, 반환된 결과를 통해 다른 처리를 하기 위해 콜백함수를 사용한다.

에러처리 한계

에러처리는 서비스 완성도면에서 굉장히 중요하다. 많은 개발자들이 이를 간과하는데 서비스를 사용하는 유져입장에서는 에러처리가 굉장히 중요하다. 콜백 방식의 비동기 처리는 에러처리가 곤란하다.

 

try {
  setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
  console.log('에러를 캐치하지 못한다..');
  console.log(e);
}

 

위의 예시를 보면 try에서 콜백함수가 예외를 발생시키지만 catch에서 잡히지 않는다. 왜냐하면 setTimeout의 콜백함수의 호출자는 setTimeout 함수가 아니기 때문이다. 콜백 함수의 호출자가 setTimeout이라면 호출 스택에 setTimeout 함수가 존재해야 하기 때문이다. 예외는 호출자 방향으로 전파된다. 하지만 위의 예시는 호출자와 부합하지 않기에 catch에서 잡을 수 없다. 이를 극복하기 위해 promise가 제안되었다.

Promise

Promise는 생성자 함수를 통해 인스턴스화 한다. 생성자 함수는 비동기 작업을 수행할 콜백 함수를 인자로 전달받는데 resolve와 reject를 함수로 전달받는다. 상태는 pending, fulfiled, rejected, settled가 있다.

const promiseAjax = (method, url, payload) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.setRequestHeader('Content-type', 'application/json');
    xhr.send(JSON.stringify(payload));

    xhr.onreadystatechange = function () {
      // 서버 응답 완료가 아니면 무시
      if (xhr.readyState !== XMLHttpRequest.DONE) return;

      if (xhr.status >= 200 && xhr.status < 400) {
        // resolve 메소드를 호출하면서 처리 결과를 전달
        resolve(xhr.response); // Success!
      } else {
        // reject 메소드를 호출하면서 에러 메시지를 전달
        reject(new Error(xhr.status)); // Failed...
      }
    };
  });
};
/*
      비동기 함수 promiseAjax은 Promise 객체를 반환한다.
      Promise 객체의 후속 메소드를 사용하여 비동기 처리 결과에 대한 후속 처리를 수행한다.
    */
    promiseAjax('GET', '<http://jsonplaceholder.typicode.com/posts/1>')
      .then(JSON.parse)
      .then(
        // 첫 번째 콜백 함수는 성공(fulfilled, resolve 함수가 호출된 상태) 시 호출된다.
        render,
        // 두 번째 함수는 실패(rejected, reject 함수가 호출된 상태) 시 호출된다.
        console.error
      );

위 처럼 reject를 통해 에러처리를 할 수 있다.

then은 promise의 후속 처리를 위한 메소드로 두 개의 콜백 함수를 인자로 전달 받는다. 첫번째 콜백 함수는 성공시 호출되고 두번째함수는 실패 시 호출된다. then은 promise를 반환한다.

promiseAjax('<https://jsonplaceholder.typicode.com/todos/1>')
  .then(res => console.xxx(res))
  .catch(err => console.error(err)); // TypeError: console.xxx is not a function

그리고 여기서는 catch를 이용하여 에러를 잡을 수 있다. 가독성도 콜백에 비해 훨씬 명확하다.

Promise 체이닝

그리고 promise는 호출이 중첩되어 복잡도가 높아지는 콜백헬을 해결할 수 있다. then 메소드를 통해서 중첩이 아닌 체이닝 형식으로 여러 함수를 중첩할 수 있다.

 

여기까지 알아보았다. 참고한 사이트가 너무 자세히 잘 설명해 있어서 쉽게 해결한것 같다. 저 딥다이브 책이 확실히 좋은듯 하다 사고 싶은데 4.5는 너무 비싸다..

 

면접시 대답을 한마디로 정리하면

 

Promise는 JavaScript에서 하는 비동기 통신 패턴입니다. 기존의 사용하던 콜백 방식의 약점을 보완하여 나온 패턴으로 가독성을 높이고 콜백지옥을 피할 수 있으며 비동기 처리 시점을 명확히 표현할 수 있습니다.

 

추가 질문은... 상태 정도 나오려나.. 생각나면 추가로 적어보자.

참고

반응형

'취업 > 면접' 카테고리의 다른 글

Protobype 면접질문  (0) 2022.02.16
지긋지긋한 CORS! 타파!!  (0) 2021.10.16
React.memo 알아보기 (feat. React.callback)  (0) 2021.08.19
Callback 비교 - 1  (0) 2021.08.07
React 배열에 key가 존재하는 이유  (0) 2021.08.06