티스토리 뷰

* async / await ? 

Promise의 불편한 점을 개선하기 위해 ES7에서 추가된 키워드로, 비동기 코드를 마치 동기 코드처럼 보이게 작성할 수 있습니다. 일반 비동기 처리처럼 실행이 다음 라인으로 넘어가는 것이 아니라 결과값을 얻을 수 있을 때까지 기다립니다. 따라서 일반적인 동기 코드처리와 똑같은 흐름으로 코드를 작성 할 수 있습니다.

 

* promise.all 

여러 개의 프로미스를 동시에 실행시키고 모든 프로미스가 처리될 때까지 기다리는 경우 유용하게 사용할 수 있습니다. 일반적으로 다음 코드를 계속 실행하기 전에 서로 연관된 비동기 작업 여러 개가 모두 이행되어야 하는 경우에 사용합니다. 즉 프로미스들을 하나로 묶어 하나의 프로미스처럼 관리 할 수 있게 해 줍니다. 단 내부에서 프로미스들의 순서가 제어되지 않기 때문에, 프로미스 처리 순서가 중요한 경우에는 사용하면 안 됩니다.

 

1. 병목 현상

  • 테스크가 적체되는 현상

예전 프론트 메뉴 중 기능을 추가하다 보니 최종적으로 API를 연속으로 5~6개 호출하여 처리한 로직이 있었는데, async / await으로 처리하여 병목 현상이 발생해, 속도가 느려져 promise.all로 바꾸어 속도 개선을 진행한 경험이 있습니다.

 

2. 개선 방법

  • 1초, 2초, 3초 후 특정 문자열은 반환하는 promise 함수 3개를 정의한 후 

     - 1) async / await 을 통한 처리
     - 2) promise.all()  을 통한 처리

    를 비교해보겠습니다.
funcA = async () => {
        return new Promise((res) =>
            setTimeout(() => {
                res('funcA pass');
            }, 1000)
        )
    }

funcB = async () => {
        return new Promise((res) =>
            setTimeout(() => {
                res('funcB pass');
            }, 2000)
        )
    }

funcC = async () => {
        return new Promise((res) =>
            setTimeout(() => {
                res('funcC pass');
            }, 3000)
        )
    }
  • 먼저 1초, 2초, 3초 후 특정 문자열을 반환하는 함수 3개를 정의합니다.
let startTime = new Date().getTime();

console.log(await this.funcA());
console.log(await this.funcB());
console.log(await this.funcC());

let endTime = new Date().getTime();

console.log(`${(endTime - startTime) / 1000} s`);

  • async / await 을 통한 처리 결과 약 6초가 걸리는 것을 알 수 있습니다.
let startTime = new Date().getTime();

await Promise.all([this.funcA(), this.funcB(), this.funcC()]).then((res) => {
     console.log(res)
});

let endTime = new Date().getTime();

console.log(`${(endTime - startTime) / 1000} s`);

  • promise.all()  을 통한 처리 결과 약 3초가 걸리는 것을 알 수 있습니다. 

 

3. async/await , promise.all 비교

async/await 동작 방식

  • async/await은 프로미스의 상태가 완료될 때까지 기다린 후 다음 코드를 순차적으로 실행합니다.

 

promise.all 동작 방식

  • promise.all 은 여러 프로미스들을 병렬적으로 실행하고, 가장 마지막 태스크가 완료될 때 완료 상태를 반환합니다. 
    ( * 주의점 : promise.all은 내부 프로미스의 순서들이 제어되지 않기 때문에, 프로미스의 실행 순서가 중요한 경우에는 사용하면 안 됩니다. 즉 함수들 간의 의존성이 없을 때 이용하면 상당히 좋은 시간 절감 효과를 볼 수 있습니다.)

 

🤔  정리 !

  • 실행할 순서가 중요하지 않다면 (ex. 데이터 단순 업데이트) => Promise.all
  • 실행할 순서가 중요하다면 (ex. 페칭 해서 가져온 데이터의 정보를 다음 함수의 파라미터로 사용) => async/await

 

 

웹 환경에서 처리 속도는 사용자들의 만족도와 경험에 크게 영향을 미친다! 항상 쉽게 처리하는 것보다는 더 좋은 개선방향으로 공부해보고 적합하다면 적용하는 습관을 가지자!

 

 

🔗 참고한 글

 

async/await 병목현상 줄여보기 | devlog.akasai

블로그 글을 보다 나는 지금 어떻게 개발하고 있는지 궁금해서 직접 테스트해보았다. async/await를 습관적으로 쓰고 있지만, 잘 쓰고 있는지 되돌아보는 계기가 되었다. Async/Await의 병목현상 Promise

akasai.space

'JavaScript' 카테고리의 다른 글

JS - 호이스팅 (Hoisting) ?  (0) 2022.07.05
JS - Lodash ?  (3) 2022.07.04
JS - 복사한 값, 붙여넣기 이벤트  (0) 2022.05.12
JS - 화살표 함수(Arrow function)  (0) 2022.04.22
JS - this 란?  (0) 2022.04.21
댓글