ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NodeJS] 자바스크립트 비동기 연산을 다루는 async/await
    💫 Computer Science/Web 2020. 10. 20. 16:39

     

    자바스크립트의 비동기를 다루는 async/await

     

    콜백함수의 콜백지옥을 탈출하게 해주는 Promise, 그리고 또 Promise의 단점을 보완해주는 async/await.

    async/await은 Promise와 다른 개념이 아니고 Promise를 사용하는 패턴이니 Promise의 이해가 선행되어야 합니다.

    Promise 포스팅 참고하기

     

     

    인간의 욕심은 끝이 없고 보완의 보완을 거듭하는 패턴은 계속 나옵니다.

    현재 비동기 연산을 다루는 패턴 중 가장 쉽게 접근할 수 있는 방법인 async/await는 비동기 처리의 꽃 이라고 할 수 있습니다.

     

     

    왜 callback, promise로도 비동기 처리가 가능한데, async/await까지 알아야 할까요?

     

    가장 큰 이유는 여전히 Promise도 가독성이 썩 좋지 않다는 점입니다. 코드가 깔끔하고 가독성이 좋아야 눈으로 로직 파악이 가능하고 디버깅이 쉬워지기 때문이죠. 그리고 또 async/await로 코드의 양도 줄일 수 있습니다.

     

     


     

    const makeRequest = () =>
        getJSON()
        .then(data => {
            console.log(data);
            return "done";
        })
        
    makeRequest();

    먼저 Promise로 작성된 makeRequest()라는 함수를 살펴봅시다.

     

     

    const makeRequest = async () => {
        console.log(await getJSON());
        return "done";
    }
    
    makeRequest();

    그리고 이건 async/await으로 작성된 똑같은 코드입니다. 이 쪽이 훨씬 더 깔끔하고 직관적이지 않나요.

     

     

     

     


     

    async 사용하기

     

    function workP(sec) {
      return new Promise((resolve, reject) => {
          setTimeout(() => {
              resolve(new Date().toISOString());
          }, sec*1000);
      });
    }
    
    function justFunc() {
      return 'just Function';
    }
    
    async function asyncFunc() {
      return 'async Fucntion';
    }
    
    console.log(justFunc());
    console.log(asyncFunc());
    console.log(workP());

    여기 3가지의 함수가 있습니다. 

     

    • workP() : Promise로 구현된 함수
    • justFunc() : 일반 함수
    • asyncFunc() : async를 사용한 함수

     

    이 세 함수의 정보를 로그에 찍어보면 이와 같습니다.

     

    일반 함수인 justFunc()은 리턴으로 준 문자열 'jusf function'이 그대로 리턴되지만,

    asyncFunc()과 workP()는 둘 다 Promise 객체를 리턴하는 것을 확인할 수 있습니다.

     

    async는 Promise객체를 리턴하기 때문이죠.

     

     

    async function asyncFunc() {
      return 'return value';
    }
    
    asyncFunc().then((result) => {
      console.log(result)
    });

    Promise객체를 리턴하기 때문에 .then()을 연결해 다음 동작을 넣을 수 있습니다. 여기서 .then의 파라미터로 넘겨준 result는 asyncFunc()에서 리턴하는 값이고, 이를 Promise의 then으로 받게됩니다.

     

     

    async는 함수를 선언할 때 앞에 붙이고 그 함수를 Promise를 리턴하는 함수로 만들어줍니다. 그 전에는 new Promise()를 통해서 Promise 객체를 만들어주고 Promise를 리턴했지만, 그 과정을 숨길 수 있게 되어 코드가 짧아졌습니다. 또 Promise에서 사용했던 resolve는 async/await에서 return과 동일합니다.

     

     

     


     

    await 사용하기

     

    function workP(sec) {
      return new Promise((resolve, reject) => {
    
          setTimeout(() => {
              resolve('workP function');
          }, sec*1000);
      });
    }
    
    async function asyncFunc() {
      const result_workP = await workP(3);
      console.log(result_workP);
      return 'async function';
    }
    
    asyncFunc().then((result) => {
      console.log(result)
    });

    asyncFunc()을 보면, 여기서 workP()의 결과가 나중에 리턴된 것을 볼 수 있고 이는 비동기식으로 함수가 실행되었다는 것을 의미합니다. 여기서 workP()의 결과를 받은 후에 asyncFunc()을 실행하고 싶다면 어떻게 해야할까요? 이때 사용하는 것이 바로 await입니다.

     

     

     

    async function asyncFunc() {
      await workP(3);  
      return 'async function';  
    }  

    workP()함수를 호출하기 전에 await만 걸어 실행해 봅니다. 그러면 3초 뒤에 'aync function'  문자열이 콘솔에 찍히게 되는데, 이는 workP()실행 후 asyncFunc()이 실행되었고 동기적으로 코드가 실행된 것을 확인할 수 있습니다.

     

     

    function workP(sec) {
        return new Promise((resolve, reject) => {
    
            setTimeout(() => {
                resolve('workP function');
            }, sec * 1000);
        });
    }
    
    async function asyncFunc() {
        const result_workP = await workP(3);
        console.log(result_workP);
        return 'async function';
    }
    
    asyncFunc().then((result) => {
        console.log(result)
    });

    await을 붙이면 await이 붙은 함수의 실행이 끝나는 동안 기다리게 되므로 다음 코드를 실행할 수 없게 됩니다. 그리고 await을 붙인 함수의 결과 값을 변수에 넣어 위 예제처럼 출력할 수 있고 then을 이용해 다음 로직을 연결해 주어도 됩니다.

     

     

     

    댓글

Designed by Tistory.