[Javascript] async/await

Bam·2022년 2월 28일
0

Javascript

목록 보기
79/106
post-thumbnail

지난 포스트에서 다룬 Promise 객체는 기존의 콜백 지옥을 크게 개선시켜준 문법입니다. 하지만 이 역시도 비동기 처리가 늘어날수록 then, catch 메소드가 꼬리를 이어 코드가 복잡해집니다. 그래서 ES8에서는 asyncawait라는 문법을 도입해서 프로미스 객체들을 더욱 간결하게 만들어주었습니다.

기본 사용법

asyncawait는 다음과 같이 사용합니다. async는 비동기 처리 함수 앞에, await는 프로미스 객체의 앞에 키워드를 사용합니다.

async function 함수명(){
}

await 프로미스;

구체적인 예시는 대표적 비동기 처리 함수인 setTimeout() 메소드를 가지고 알아보겠습니다.

setTimeout이 비동기인 이유

setTimeout 메소드는 특정 시간이 지난 후 코드를 실행합니다. 즉, setTimeout이 호출되면 카운트를 실행하고 일정 시간 후에 메소드 내부의 코드를 실행하는데, 이 카운트를 세는동안 브라우저는 계속해서 스크립트를 읽어나갑니다. 따라서 setTimeout은 비동기 처리 함수의 가장 대표적인 예시라고 볼 수 있습니다.



먼저, 지난 포스트에서 다룬 Promise 객체를 이용한 비동기 처리 코드를 보겠습니다. setTimeout을 사용해서, 함수가 호출되고 1초 후에 문자열을 출력하는 코드입니다.

function func() {
    console.log('func() 실행 중');

    return new Promise((resolve => {
        setTimeout(resolve('promise'), 1000);
    }));
}

func().then((message)=> {
    console.log(message);
})
.catch((errorMessgae)=>{
    console.log(errorMessgae);
});


물론 간단한 코드라서 프로미스 객체를 사용해도 그렇게 복잡하다고 느끼지 못 할 수도 있습니다. 그러면 위 코드를 async를 사용해서 바꿔보겠습니다.

async function func() {
    console.log('func() 실행 중');

    return 'promise with async';
}

func().then((message)=> {
    console.log(message);
})
.catch((errorMessgae)=>{
    console.log(errorMessgae);
});


프로미스를 return 하는 구문이 굉장히 간단해지지 않았나요? 위처럼 함수 앞에 async키워드를 붙이면 결과로는 항상 프로미스 객체를 반환합니다. 만약 async키워드가 없다면, 문자열을 반환했다고 했을 것 입니다. async가 붙은 함수는 자동적으로 resolve가 된 프로미스 객체를 반환합니다.

이번에는 await도 사용해보겠습니다. awaitasync 키워드가 붙은 함수 내부에서만 사용가능한 키워드입니다. await는 비동기 처리 함수 내부에서 지정한 프로미스 객체가 resolve 될 때 까지 기다리는 기능을 합니다. 역시, 방금전에 사용했던 코드에 await 구문을 추가해보겠습니다.

console.log('func() 시작');
func();
console.log('func() 종료');

async function func() {
    console.log('func() 실행 중');

    const promise = new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve('await', 1000);
        });
    });
    
    console.log(await promise);
}

일반적으로 생각했을 때, 시작 -> 실행 중 -> await -> 종료의 순서대로 반환할 것 같지만 아닙니다. 순서대로 실행은 하되, 비동기 처리 함수를 부르고나서 실행 완료까지 기다리지 않고 계속 스크립트를 해석합니다. 그리고 await가 완료되면 그제서야 해당 부분의 코드를 실행합니다.

코드에서 비동기 처리부분만 따로 떼어보면, 기존의 프로미스 객체의 them, catch 구문보다 확실히 간결해졌음을 알 수 있습니다.

async function func() {
    const promise = new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve('await', 1000);
        });
    });

    console.log(await promise);
}

async, await 구문에서 error잡기

프로미스 객체를 사용할 때는 catch 구문을 사용해서, 프로미스가 reject된 경우를 처리했습니다. 그러나 async, await에는 reject되는 경우를 처리하는 구문이 보이질 않습니다.

asyncawait을 사용할 때 reject는 try~catch구문으로 처리를 합니다. 비동기 처리 함수 내에서 처리 부분은 try에 넣고, catch에 실패 시(=프로미스가 reject인 경우)의 처리를 기술하면 됩니다.

async function func() {
    try{
        const promise = new Promise((resolve, reject) => {
            setTimeout(()=>{
                resolve('await', 1000);
            });
        });

        console.log(await promise);
    }
    catch (e) {
        console.log(e);
    }
}

0개의 댓글