관리 메뉴

꿈꾸는 개발자

async & await에 대한 이해 본문

프로그래밍언어/Javascript

async & await에 대한 이해

rickysin 2022. 11. 27. 17:27

생활코딩 영상 참고

  • await에 대한 이해:

  • 그림에 나온 것처럼, 좌측에 있는 promise-then() 형식의 코드를 오른쪽처럼 단순화하기 위해서는 각 promise함수에 await란 keyword을 붙여야 한다=> 추가로, await은 function() 내에 사용돼야 하며, await을 포함하고 있는 function은 async란 keyword를 앞에 추가해야 한다!  run()함수를 호출하면 왼쪽과 오른쪽 코드는 완전히 똑같은 동작을 하게 된다! 
  • await/async를 사용하지 않은 코드:
      function timer(time) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(time);
          }, time);
        });
      }
      console.log("시작");
      timer(1000)
        .then((time) => {
          console.log("time:" + time);
          return timer(time + 1000);
        })
        .then((time) => {
          console.log("time:" + time);
          return timer(time + 1000);
        })
        .then((time) => {
          console.log("time:" + time);
          console.log("end");
        });
      //console.log("end");

마지막 console.log("end")을 then()내부에 넣지 않으면 마지막이 아닌, 시작 다음에 바로 출력되게 된다=> 실행 컨텍스트와 비동기 처리의 동작 원리를 떠올리면 이해할 수 있다! 

 

  • 위의 코드를 동기적으로 작동하는 것처럼 작성하는 법(await/async 사용!)
      let time = await timer(1000);
      console.log('time:'+time);
      time= await timer(time+1000);
      console.log('time:'+time);
      console.log(time);
      time= await timer(time+1000);
      console.log('time:',time);

위의 코드와 밑에 코든 정확하게 일치한다고 보면 된다! 

하지만 async 함수 내부에서 작성하지 않는 이상 위와 같은 error message를 표시하게 된다! 

  • 위 두 코드는 동일한 결과값을 도출하게 된다! 
      async function runs() {
        console.log("시작");
        let time = await timer(1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        console.log("end");
      }
      console.log("parent start");
      runs();
      console.log("parent end");

  • 일반적으로 async 처리된 함수는 promise를 return한다=> 따라서,function 내부의 await는 다 비동기적으로 처리되는 것으로 보인다=>따라서, 위와 같은 실행 결과가 나온다=> 하지만 이것은 곧 runs() 함수도 promise이기 때문에 앞에 await을 추가할 수 있음을 의미한다! 
    async function runs() {
        console.log("시작");
        let time = await timer(1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        console.log("end");
      }
      async function runs2() {
        console.log("parent start");
        await runs();
        console.log("parent end");
      }
      runs2();
  • 코드의 형태를 위와 같이 변경하면 원했던 방식으로 출력이 이루어진다! 

  • 정리: 
    • async라는 키워드는 평범한 함수를 promise를 return하는 함수로 만들어주는 역할 담당! 
    • 따라서, async 함수 내부에서 await를 사용할 수 있게 된다 =>promise이기 때문에! 
  • 최종 분석 코드: 
      function timer(time) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(time);
          }, time);
        });
      }
      async function runs() {
        console.log("시작");
        let time = await timer(1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        time = await timer(time + 1000);
        console.log("time:" + time);
        console.log("end");
        return time;
      }
      async function runs2() {
        console.log("parent start");
        let time = await runs(); //runs는 호출되고, time에 reference가 저장된다!
        console.log("time:" + time);
        console.log("parent end");
      }
      console.log("parent parent start");
      runs2().then((/*비워놔도 괜찮다!*/) => {
        console.log("parent parent end");
      });

결과값!