JS/JavaScript&TypeScript

JavaScript&TypeScript 14. 비동기 함수

shin96bc 2022. 4. 3. 12:33

(1) 비동기 함수( Async Function ) ( TypeScript )

     Github: https://github.com/SHIN96BC/JavaScript-TypeScript-Concept-2022/tree/main/14_AsyncFunction

     1) JavaScript 에서는 코드를 딜레이 시킬 수 있는 방법이 없다. 예를 들어 5번째 코드를 실행하고

         3초 있다가 6번째 코드를 실행 하는 방법은 존재하지 않는다.

     2) JavaScript 에서 이런 딜레이를 주려면 타이머를 이용해서 callback 함수를 제공한 다음에 

         특정시간 이후에 그 callback 함수가 호출되는 그런 패턴의 코드를 작성해야할 것이다.
         ( 즉, 일반적인 코드를 동기적으로 한줄 한줄 작성하면서 딜레이를 걸 수 있는 방법은 없다. )

     3) 비동기 코드를 처리하는 방법
          ex) Promise 객체를 반환하는 함수가 있다.
              function delay(ms: number): Promise<string> {
                   return new Promise((resolve, reject) => {
                        setTimeout(() => {
                             if(Math.floor(Math.random() * 10) % 2 === 0) {
                                  resolve('success');
                             } else {
                                  reject('failure');
                             }
                        }, ms);
                   });
              }

          <1> promise 패턴
               1> 이 함수를 기존의 promise 패턴을 사용해서 처리하게 되면 then 이라고 하는 메소드에 

                    callback 함수를 제공함으로써, 내가 원하는 코드를 성공 이후에 실행 시킬 수 있었다.
 
               2> 실패했을때는 catch 메소드에 callback 함수를 제공해서 처리한다. 

               3> 이 promise 패턴은 then 과 catch 에 callback 함수를 제공해야하는 

                     비동기 프로그래밍 코드이다.

               4> 하지만 우리가 하고 싶은것은 이런 callback 으로 제공되는 비동기 코드가 아니라, 
                  한줄 한줄 일반적인 동기 코드처럼 비동기 코드를 사용하고 싶은 것이다.
                  그럴때 비동기 함수를 사용한다.


          <2> 비동기 함수
               1> 이 함수를 비동기 코드가 아니라 동기 코드처럼 사용할 때 비동기 함수를 사용한다.
               2> 비동기 함수 앞에는 'async' 라는 지시어를 붙인다.
               3> 그리고 기존의 promise 객체를 반환하는 함수가 있다면, 그 함수 앞에 'await' 라고 

                    하는 오퍼레이터를 붙여준다.
                    ex)
                        async function main() {
                             try {
                                  console.log('start job');
                                  const result = await delay(3000);
                                  console.log(('done async!' + result));
                             } catch (e) {
                                  console.error('fail async!' + e);
                             }
                        }

               4> 이렇게 작성하게 되면 callback 함수를 사용하지 않았는데 마치 3초정도 지연이 있다가 

                     그 다음 라인으로 넘어온 것처럼 보인다. 하지만 이건 명백히 백그라운드에서 

                     비동기 작업이 실행된 거기 때문에, ajax 의 호출 옵션을 강제로 동기로 해서 작업할 때 처럼 

                     UI가 막히거나, 멈칫거리거나, 움직여지지 않거나 하는 문제점들이 발생하지 않는다.

               5> 비동기 함수는 실제로 동작하는건 비동기로 작동을 하고, 코드적으로만 동기적으로 

                    작동하는 것처럼 보이게 만들어준다.

     4) 정리
          <1> 비동기 함수는 원하는 함수 앞에 'async' 를 붙여주고, Promise 객체를 반환하는 함수 앞에 

                 'await' 를 붙여주기만 하면, Promise 를 반환하는 작업( 여기서는 delay 가 된다. ) 

                 즉, resolve 라는 함수가 호출되면 'success' 라고 하는 데이터가 마치 리턴돼서 

                 넘어오는 것처럼 코드를 기술할 수 있게 되는 것이다.

          <2> 에러 즉, reject 는 예외 구문에 걸리게된다.
              그래서 항상 'await' 를 try catch 로 감싸서 에러는 catch 구문에서 처리하게 해주면 된다.

          <3> 비동기 함수 자체는 간단하지만, 중요한건 이 비동기 함수 조차도 Promise 베이스의 메커니즘 

                 위에서 작동되는 코드이기 때문에,  Promise 의 메커니즘을 충분히 이해하는 것이 

                 무엇보다 중요하다.