javascript promise로 sleep() 함수 개발하기

고광필·2023년 1월 29일
0

Front

목록 보기
31/33

프로그래머스 데브코스를 수강하고 2022년 9월 ~ 10월에 많은 회사에 지원하고 면접을 봤을 때, 2곳에서 api 요청 외에 promise를 사용하는 코드를 물어봤습니다

공통적으로 sleep을 만드는 코드였는데 2곳 모두 대답하지 못했었고, 이후에 찾아보지도 않았던 내용을 최근에야 다시 공부합니다

sleep 관련 면접 상황

다른 언어들은 어느 시간동안 기다리도록 하는 sleep 함수가 있는데, 자바스크립트에는 그게 없습니다. 그럼 sleep을 직접 만들어서 사용한 사람들은 어떻게 만들었을까요?

사실 sleep이 없는지도 몰랐습니다...

setTimeout(sleep 뒤에 실행할 콜백, second) 처럼 개발했을거라고 답변했었습니다

네 코드 실행은 어느 시간동안 기다리고 실행할 수 있겠네요. 혹시 더 개선할 점은 없을까요?

코드 실행은 맞는 것 같고, 한줄짜리 코드인데 문제가 될 내용이라면 콜백인가?

sleep 함수를 중복으로 사용하거나, 콜백 함수가 또 콜백을 사용하는 등 콜백지옥이 일어날 가능성이 있는 코드입니다

근데 비동기 콜백 지옥을 promise로 개선할 수 있을텐데, 어떻게 할지를 모르겠네...

결국 콜백지옥 문제가 있고, promise로 이를 개선할 수 있지만 구체적으로 코드를 어떻게 작성할지는 모르겠다고 했습니다

이후 이 내용을 공부하지 않고, 다른 기업 면접에서도 유사 질문을 받았는데 역시 대답하지 못했습니다

promise를 이용한 sleep()

api 요청에 대해서만 promise를 사용했었는데, 관련 코드를 보면서 다시 생각해보겠습니다

fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => response.json())
      .then(json => console.log(json))

위 코드는 jsonplaceholder의 예시 코드입니다
todo를 1개 가져오고, 가져왔으면 json으로 바꿔줍니다
json으로 바꿨으면 출력합니다

이게 then을 통해 비동기가 완료되었을 때 이루어지는 이유는 서버 상황이나 클라이언트의 네트워크 상황에 따라 느려질 수 있기 때문입니다

즉, 정확하게 todo를 1개 가져온 시점을 알 수 없습니다

promise는 비동기 요청이 완료되었을 때 어떻게 처리할지 then에 작성한다

그럼 이 내용을 바탕으로 생각해보면 sleep() 함수의 then 콜백에 sleep 이후 실행할 콜백이 들어가면 됩니다

그리고 sleep은 그 시간 이후에 완료(resolve)되어야 하므로 아래와 같은 코드를 개발할 수 있습니다

const sleep = second => new Promise(resolve => setTimeout(resolve, second));

// then
sleep(3000).then(sleep 이후 실행할 콜백)

// async await
await sleep(3000);
/*
  sleep 이후 실행할 코드
*/

작성하고 보니 코드가 직관적이죠?
n초 이후에 완료하는 promise를 반환하고, promise가 완료된 이후 뭔가를 하는 코드입니다

특정 상황 처리 추가

sleep() 함수가 최소 3초를 기다려야 한다고 가정하겠습니다
그럼 3초보다 낮은 시간을 기다리는 명령이 왔을 때 어떻게 처리할 수 있을까요?

const sleep = second => {
  if (second < 3000) {
    second = 3000;
  }

  return new Promise(resolve => setTimeout(resolve, second));
};

3초보다 낮은 값이 오면 지정한 최소 시간인 3초로 맞추거나

const sleep = (second) => {
  return new Promise((resolve, reject) => {
    if (second < 3000) reject('sleep은 무조건 3초 이상으로 쓰세요')
    else setTimeout(resolve, second))
  }
}
const sleep = second => {
  if (second < 3000) return Promise.reject('sleep은 무조건 3초 이상으로 쓰세요');
  else return Promise.resolve(setTimeout(resolve, second));
};

reject 처리를 할수도 있겠습니다
할 수 있긴한데...근데 custom promise에서 이런 경우가 있을까요?

정리

면접 때 2번이나 답변 못했던 내용을 공부했습니다
api 통신 외에도 custom promise로 resolve, reject를 사용해보면서 promise에 대해 더 공부할 수 있었습니다

참고

jsonplaceholder

profile
이해하는 개발자를 희망하는 고광필입니다.

0개의 댓글