택택
109
2021-01-24 03:34:25
7
407

프로미스, async, await 질문입니다! 고수님들 도와주세요!


프로미스와 에이싱크 어웨잇을 학습 중입니다.


async function load() {
  for (var i = 0; i < 3; i++) {
    console.log(i);
    await timer(1000);
  }
  console.log("end");
}

async function timer(ms) {
  return setTimeout(() => {}, ms);
}

load();

라는 함수를 실행시키면 제 예상은 1초마다 숫자가 찍히는줄 알았지만 한번에 숫자가 나옵니다.


timer 함수를

const timer = (ms) => new Promise((res) => setTimeout(resms));

로 바꾸면 정상작동합니다.

그렇다면

const timer = (ms) => new Promise((res) => setTimeout(resms)); 와

async function timer(ms) {
  return setTimeout(() => {}, ms);
}

가 서로 다르다는 거 같습니다.

뭐가 문젠가요?

async에서 return하면 resolve로 들어가는거 아닌가요?


글 읽어주셔서 감사합니다

0
  • 답변 7

  • 김룰룰룰
    579
    2021-01-24 09:20:13

    setTimeout은 동기 함수이기 때문에 Promise로 감싼다 한들 동기 값을 await 연산자에 전달한 것과 동일하게 처리될 겁니다. 

    function timer() {
        return Promise.resolve(setTimeout(...)).then(() => undefined);
    }

    즉 위의 코드와 같으며 Promise.resolve 역시 동기 코드로 호출되기 때문에 동기적인 코드와 100% 같은 속도로 처리될 겁니다.

    원래 timer를 promisify할 때도 resolve를 setTimeout의 콜백으로 주는 게 핵심인데 이를 생략할 수는 없죠.

  • 택택
    109
    2021-01-24 11:50:28

    김룰룰룰


    선생님 그러면 setTimeOut에 콜백으로 리졸브를 주면

    async function timer(ms) {
      setTimeout(() => {
        return 1;
      }, ms);
    }

    이렇게 리턴을 시켜주면 리졸브 값으로 1이 들어가지 않을까 라는 생각을 했는데, undefined가
    뜨네요..

    이 코드에선 무슨 문제가 있는 걸까요? async를 사용하여 timer를 만든다면
    어떤 수정이 필요할까요?

    답변 정말 감사합니다 ;)

  • charlatan
    3k
    2021-01-24 15:56:37

    async-await 사용예를 오해하고 있는 듯 합니다만? async를 쓰고 그 함수에서 return을 하면 Promise가 리턴된다라고 생각하는 것 같은데 그렇게 설명되어 있는 자료가 있는지요?

  • 김룰룰룰
    579
    2021-01-24 16:47:44

    @택택

    제가 작성한 원 답을 보니 너무 성의가 없었던 것 같습니다...

    async로 timer를 만든다면 글쓴님이 원래 올려주신 그 예시가 맞습니다. 이것이 작동하는 이유는 직접 resolve를 호출하는 callback이 있기 때문이죠.

    const timer = (ms) => new Promise((res) => setTimeout(resms));

    setTimeout은 반환값이 없는 (= undefined) 함수입니다.

    그러므로 setTimeout을 Promise.resolve 로 감싸도 resolve 되는 값은 항상 undefined 입니다.

    setTimeout 함수 자체는 JS의 비동기 생태계와는 전혀 관련이 없는 '동기' 함수이며 반환값도 없습니다. 이 함수로 인해 이벤트 루프 queue에 들어가는 callback 함수랑은 실행 흐름 면에선 전혀 관련이 없죠.(호출 스택도 같은 게 아니고요)

  • 택택
    109
    2021-01-24 16:58:06 작성 2021-01-24 16:58:28 수정됨

    freestyle


    https://velog.io/@ejchaid/async-await


    이 글 중간에 

    async 함수는 Promise를 리턴한다

    async function a() {
        return 1;
    }
    let result = a(); // Promise {<resolved>: 1}

    일반적으로 async / await 는 비동기 함수를 처리하기 위해 사용한다. 하지만, 비동기 처리가 없는 일반적인 함수에 async를 붙이면 리턴해주는 값을 resolve로 감싼 Promise를 리턴해준다.


    라는 구문을 보고 저런 식으로 코드를 작성하면 되지 않을까 라는 생각을 햇습니다...

  • 택택
    109
    2021-01-24 17:00:20

    김룰룰룰


    아닙니다 저는 글 읽어주시고 답변 달아주신거로 너무 감사합니다!


    다시 한번 비동기에 대해 공부하고 코드를 작성해 볼게요!  감사합니다 :)

  • 김룰룰룰
    579
    2021-01-24 17:12:29

    감사합니다 ㅎㅎ. JS의 비동기 생태계나 async-await의 작동 방식에 대해서 조금 더 자세히 알고 싶으시다면 generator로 비동기 코드를 처리하는 방법에 대해 공부해보시면 매우 좋을 것입니다 :)

  • 로그인을 하시면 답변을 등록할 수 있습니다.