ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ES6+ | Async Await
    JavaScript/ES6+ 2020. 5. 18. 14:42

    Async Await

    async await은 비동기 프로그래밍을 동기 프로그래밍처럼 작성할 수 있도록 함수에 추가된 기능

    • ES2017에 자바스크립트 표준으로 등록
    • 프로미스의 then 메서드를 체인 형식으로 호출하는 것보다 가독성이 좋음
    • 프로미스는 비동기 상태를 값으로 다룰 수 있는 async await 보다 큰 개념으로,
      async await이 프로미스를 완전히 대체할 수는 없음

    async await 이해

    async await 함수는 프로미스를 반환

    프로미스는 객체로 존재하지만 async await은 함수에 적용되는 개념

    async function getData() {
        return 123;
    }
    getData().then(data => console.log(data));
    // 123
    // Promise {<resolved>: undefined}
    
    async function getData() {
        return Promise.resolve(123);
    }
    getData().then(data => console.log(data));
    // 위의 함수와 동치
    
    async function getData() {
        throw new Error('123');
    }
    getData().catch(error => console.log(error));
    // Error: 123
    • async 키워드로 정의된 함수는 async await 함수이며, 항상 프로미스를 반환
    • 프로미스를 반환하기 때문에 then 메서드 사용 가능
    • async await 함수 내부에서 프로미스를 반환하면 그 객체를 그대로 반환
    • async await 함수 내부에서 예외가 발생하는 경우, 거부됨 상태의 프로미스 반환

    await 키워드 사용법

    • await 키워드는 async await 함수 내부에서 사용
    • await 키워드 오른쪽에 프로미스를 입력하면 그 프로미스가 처리됨 상태가 될 때까지 기다림
    • 즉 await 키워드로 비동기 처리를 기다리면서 순차적으로 코드 작성 가능
    • await 키워드는 오직 async await 함수 내에서만 사용 가능
      → 일반 함수에서 사용 시 에러 발생

    async await 사용례

    function requestData(value) {
        return new Promise(resolve =>
            setTimeout(() => {
                console.log('requestData:', value);
                resolve(value);
            }, 1000),
        );
    }
    async function getData() {
        const data1 = await requestData(10);
        const data2 = await requestData(20);
        console.log(data1, data2);
        return [data1, data2];
    }
    getData();
    // requestData: 10
    // requestData: 20
    // 10 20
    • requestData 함수가 반환하는 프로미스가 처리됨 상태가 될 때까지 getData 함수 내부의 console.log()는 실행되지 않음

    async await 활용

    비동기 함수 병렬 실행

    // 순차적 실행
    async function getData() {
        const data1 = await awaitFunc1();
        const data2 = await awaitFunc2();
        // ...
    }
    
    // 병렬 실행
    async function getData() {
        const p1 = awaitFunc1();
        const p2 = awaitFunc2();
        const data1 = await p1;
        const data2 = await p2;
        // ...
    }
    
    // Promise.all
    async function getData() {
        const [data1, data2] = await Promise.all([asyncFunc1(), asynFunc2()]);
    }
    • 두 개 이상의 비동기 함수가 실행될 때 서로 의존성이 없다면 동시에 실행하는 것이 좋음
    • 프로미스는 생성과 동시에 비동기 코드가 실행됨 즉, 프로미스를 먼저 생성하고 await 키워드를 나중에 사용하면 병렬로 실행됨
    • 위에서는 두 개의 프로미스가 생성된 후 기다리기 때문에 두 개의 비동기 함수가 병렬로 처리됨
    • Promise.all 을 사용할 수도 있음

    예외 처리

    async await 함수 내부에서 발생하는 예외는 try catch 문으로 처리하는 게 좋음

    async function getData() {
        try {
            await doAsync(); // 비동기 함수
            return doSync(); // 동기 함수
        } catch(error) {
            console.log(error);
        }
    }
    • 비동기 함수와 동기 함수에서 발생하는 모든 예외는 catch 문에서 처리
    • getData 함수가 async await 함수가 아니었다면 doAsync 함수에서 발생하는 예외는 catch 문에서 처리되지 않음
      ∵ doAsync 함수의 처리가 끝나는 시점을 알 수 없음

    참고도서: [ 실전 리액트 프로그래밍 / 저자_ 이재승 / 출판사_ 프로그래밍 인사이트 ]

    댓글

Designed by Tistory.