[JS] Async-Await 비동기 처리하기

2023. 1. 22. 22:36
반응형

이전장에서 Promise를 통해 비동기 로직을 처리하는 방법을 알아보았다.

Promise를 사용하여 가독성 좋게 콜백함수를 작성하고, 비동기 처리를 할 수 있었는데, 프로미스 체이닝이 아닌 일반적인 문법을 작성하는 것처럼 비동기 처리를 할 수 있도록 도입된 Async&Await이라는 키워드가 있다.

Async & Await의 규칙

1.  작성 방법

const p = (x, y) => {
    return new Promise((resolve, reject) => {
        const result = x + y;
        resolve(result);
    });
};

const main = () => {
    p(5000, 1000).then((x) => {
        console.log('success', x)
    });    
}

이것은 Promise를 이용하여 덧셈 코드를 만든 것이다.

const main = async () => {
    const x = await p(1000, 2000);
    console.log('success', x)
}

이제 async&await을 통해 같은 로직을 작성하였다.

Promise에서 then() 이후 콜백함수에서 작성하던 로직을 일반적인 코드 작성하는 방법으로 바꾸었다.

 

2 . Await 키워드는 Async 안에서만 사용 가능

Await의 기능은 Promise의 형태로 반환되는 비동기 함수의 실행이 완료될 때 까지 기다리는 것이다.

Await을 사용하려면 위처럼 async로 감싸진 함수 안에서만 사용이 가능하다.

 

3 . Async Function의 반환형은 Promise로 감싸져서 나온다.

const p = (x, y) => {
    return new Promise((resolve, reject) => {
        const result = x + y;
        resolve(result);
    });
};

const p2 = async (x, y) => {
    const result = x + y;
    return result;	//반환형은 Promise<any>
};

const main = async () => {
    const x = await p(1000, 2000);
    console.log('success', x)    
    
    const y = await p2(1000, 3000);
    console.log('success', y)
    
    p2(1000, 3000)
    .then((z) => {
        console.log('success', z);
    });
}

Async function의 반환형은 Promise이다. 따라서 위의 두 함수 p()와 p2()는 같은 기능을 수행하며 둘다 Promise를 반환하므로 await을 이용하거나 Promise.then()을 이용하는 방식 어느것으로나 처리할 수 있다.

 

4 . Await 키워드는 Promise로 반환되는 함수에서 사용 가능하다.

const timeOut = () => {
    setTimeout(() => {
        console.log('Time out');
    }, 3000);
}

const main = async () => {
    await timeOut();
    console.log('End');
}

다음과 같이 setTimeOut()을 기다리고 싶어서 await 키워드를 사용했다고 가정해보자. 그러나 setTimeOut()은 Promise를 반환하는 함수가 아니다. 따라서 await 키워드를 사용하더라도 콘솔에는 End가 먼저 출력되게 된다.

const timeOut = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('Time out');
            resolve();
        }, 3000);
    })
}

따라서 setTimeout을 비동기 처리하기 위해서 Promise로 반환되게 하는 메서드를 생성하여 사용하면 await 키워드가 정상적으로 작동한다.

 

5 . Async-Await에서 Reject는 Try-catch로 처리한다.

const p = () => {
    return new Promise((resolve, reject) => {
        const success = true;   //성공 Or 실패
        setTimeout(() => {
            if(success){
                resolve("Complate");
            }
            else{
                reject(new Error("Error Reason"));
            }     
        }, 3000);
    });
}


const main = async () => {   
    p()
    .then((x) => {
        console.log('Result', x);
    })
    .catch(x => {
        console.log('err', x);
    })
    
    try{
        const res = await p3();
        console.log('Result', res);
    }
    catch(e){
        console.log('err', e);
    } 
}

Promise에서는 .catch()에서 Reject에서 나온 실패 사유를 받아서 사후처리를 하였었다.

Await에서는 try-catch로 묶어 안에서 Reject될 시 인자로 전달한 실패 사유는 catch문에서 처리하면 된다.

반응형

BELATED ARTICLES

more