본문 바로가기
Programming

[Javascript] async await 사용방법

by 개발자 염상진 2022. 5. 18.

 

ES8 비동기 처리 방법

 

ES8(ECMAScript 2017)에서 비동기 처리 방식으로 async / await가 도입되었다. Promise를 기반으로 작동하고, then/catch/finally 후속 처리 메소드에 콜백함수를 전달해서 비동기 처리 결과를 후속처리할 필요가 없다. 마치 동기화 프로그래밍 처럼 비동기 프로그래밍을 구현할 수 있다.

 

async

 

async 함수는 async 키워드를 사용해 함수를 선언한다. async 함수는 항상 Promise를 반환한다. 만약 async 함수가 Promise를 명시적으로 반환하지 않더라도 resolve하는 Promise를 반환하게 된다. Promise를 반환하기 때문에 async 함수 뒤로 then 후속 처리 메소드를 사용할 수 있다.

 

 

await

 

await는 Promise 상태가 setteled 상태가 될 때 까지 대기하다가 setteled 상태로 변하게 되면 Promise가 resolve한 상태를 반환하게 된다. await 키워드는 항상 async 함수 안에서 사용해야 하며, Promise 앞에 위치해야 한다.

 

 

 

async 함수 내의 await 키워드는 async 함수의 실행을 일시 중지시킨다. 이 후 전달된 Promise의 해결을 기다리고 다음 async 함수를 실행한다. 

 

 

async await 예제

 

async ~ await를 적용한 asyncFunc() 함수를 생성한다.

 

① 가장 먼저 "calling Process"가 출력된다.

② 이후 Promise가 생성된다. 이 때 Promise는 pending 상태에 있다. Promise에 전달된 resolve 콜백 함수는 마이크로태스크 큐에 저장된다. 

③ 비동기 프로그램이므로 이후 "after Process" 가 출력된다.

④ 이제 asyncFunc()은 모두 종료되고 콜 스택에서 pop() 된다. 이벤트 루프는 마이크로태스크 큐와 콜 스택을 지켜보면서 마이크로태스크 큐에 올라간 resolve() 함수를 가져와 콜 스택에 올리고 RESOLVED를 출력 후 모든 로직을 종료한다.

 

function afterFunc(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve('RESOLVED');
        }, 3000);
    });
}

async function asyncFunc(){
    console.log('calling Process');
    const result = await afterFunc();
    console.log("after Processe");
    console.log(result);
}

 

 

async / await 에러처리

 

async/await는 콜백 함수를 인자로 전달받는 비동기 함수와 달리 프로미스를 반환하는 비동기 함수로 try~catch 문으로 에러처리가 가능하다.

 

try 문으로 기본 비동기 프로그래밍 로직을 먼저 수행한다.

①가장 먼저 calling Process를 출력한다. 

② 이 후 매개변수로 resolve, reject 콜백함수를 전달받아 Promise를 생성한다. 콜백함수들은 마이크로태스크 큐에 추가된다. 비동기 로직이지만 Promise의 상태가 reject 되면서 에러 처리를 해야 하는 상황에서 after Process는 출력되지 않는다.

이유는 await 키워드에서 async 함수 실행이 일시 중지되고 반환된 값이 reject Promise기 때문에 try문을 탈출해서 바로 예외 처리 되기 때문이다.

 

③ 3초 뒤 Promise의 reject() 콜백함수가 마이크로태스크 큐에서 콜 스택으로 올라가게 되고 catch문으로 예외를 잡아서 ERORR를 출력한다. 

function afterFunc(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            // resolve('RESOLVED');
            reject("ERROR");
        }, 3000);
    });
}

async function asyncFunc(){
    
    try{
        console.log('calling Process');
        const result = await afterFunc();
        console.log("after Process"); // 실행 안됨
        console.log(result);
    }catch(e){
        console.log(e);
    }
}

 

try~catch문으로 에러처리를 하지 않으면 async 함수는 자체적으로 반환되는 결과값을 reject()한 Promise를 반환한다. 

 

asyncFunc()을 실행하면 Promise를 반환하기 때문에 이후 then과 catch를 수행할 수 있다. 결과값은 console.error()의 결과값이다.

 

function afterFunc(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            // resolve('RESOLVED');
            reject("ERROR");
        }, 3000);
    });
}

async function asyncFunc(){
    console.log('calling Process');
    const result = await afterFunc();
    console.log("after Process");
    console.log(result);
}

 

asyncFunc()
    .then(console.log)
    .catch(console.error);

 

 

 

Reference

Async Function - Making promises friendly

Javascript Promises : Introduction

What is async/await

Google Developer Web Fundamentals .. 

 

 

 

 

[Javascript] Promise란 무엇인가? ( async await 사용 방법)

How to deal with callback chain(Callback Hell)? Promise, Callback Hell을 벗어나기 위한 도구 Javascript 비동기 프로그래밍을 위해 콜백 함수를 사용하지만, 전통적인 콜백 함수 방식은 콜백 헬(Callback H..

about-tech.tistory.com

 

댓글