본문 바로가기
javascript/javascript

자바스크립트 async / await 이해하기 !

by 산코디 2023. 1. 26.

 

 

 

안녕하세요.

오늘은 지난 시간에 이어서 자바스크립트의 async와 await에 대해 포스팅하려고 합니다. 지난번에 포스팅했던 콜백과 프로미스를 먼저 보시고난 후에 이번 글을 보게 되면 이해하시는데 많은 도움이 될 거예요!

 

* 자바스크립트 콜백지옥 알아보기! https://sancode.tistory.com/70

* 자바스크립트 프로미스 이해하기! https://sancode.tistory.com/73

 

async와 await가 나오게 된 이유는 자바스크립트의 콜백 지옥과 프로미스를 조금 더 수월하게 처리하기 위해 나왔다고 이해하시면 됩니다.

자바스크립트는 동적인 처리가 많으며, 그렇기 때문에 비동기로 처리해줘야 하는 상황이 많습니다. 기능 동작을 구현하면서 조금이라도 더 수월하게 처리하기 위해서 async와 await의 사용 방법을 이해한다면 자바스크립트 프로그래밍을 하실 때 많은 도움이 되실 거예요!

 


async / await
async
function 함수 앞에 위치하며, async를 붙이게 되면 해당 함수는 프로미스를 반환하게 됨

await 
async 함수에서 프로미스가 처리될 때까지 대기

 

그럼 오늘도 간단한 예제를 통해서 알아보도록 하겠습니다 :)


예제 1

<script>
/**
 * Document load 
 */
document.addEventListener('DOMContentLoaded', () => {

    test();
});

/**
 * Task 별 Promise async 처리 및 순차 처리를 위한 await 사용
 */
async function test () {
    
    // 초기 인자 설정
    var initObj = {
        index : 1,
        text : 'Task',
    };

    // task 1 호출
    var task1Res = await task1(initObj);
    // task 2 호출
    var task2Res = await task2(task1Res);
    // task 3 호출
    var task3Res = await task3(task2Res);
}

/**
 * 1번 Task Function
 */
async function task1 (preObj) {
    return new Promise((resolve, reject) => {
        console.log(preObj.text + ' ' + preObj.index++);
        resolve(preObj);
    });
}

/**
 * 2번 Task Function
 */
async function task2 (preObj) {
    return new Promise((resolve, reject) => {
        console.log(preObj.text + ' ' + preObj.index++);
        resolve(preObj);
    });
}

/**
 * 3번 Task Function
 */
async function task3 (preObj) {
    return new Promise((resolve, reject) => {
        console.log(preObj.text + ' ' + preObj.index++);
        resolve(preObj);
    });
}

</script>

위의 예제를 보게 되면 소스 코드는 조금 길어 보이지만 반복되는 코드들이 많아 그렇게 복잡하지 않습니다. 하나씩 보도록 하겠습니다.

가장 먼저 지난번에 알아본 프로미스(Promise)를 이용해 task 함수별로 콜백 함수 처리를 해주고 있습니다. 그리고 task 함수 전체에 async 처리를 해줬습니다.


async 예시
async function task1 (preObj) {
    return new Promise((resolve, reject) => {
        console.log(preObj.text + ' ' + preObj.index++);
        resolve(preObj);
    });
}

위처럼 함수 앞에 async를 추가해 주면 해당 함수는 비동기 처리의 함수로 인식이 됩니다.

그리고 위의 함수를 호출할 때 비동기 호출을 할지 동기 호출을 할지를 정할 때 사용하게 되는 코드가 await입니다.


await 예시
var task1Res = await task1(initObj);

 

위의 async, await 예시처럼 소스 코드에서도 동일하게 적용이 되었고, await를 호출하는 함수에도 하나의 sync를 맞추기 위해 함수 앞에 async를 추가해 줬습니다.

async function test () {
    
    // 초기 인자 설정
    var initObj = {
        index : 1,
        text : 'Task',
    };

    // task 1 호출
    var task1Res = await task1(initObj);
    // task 2 호출
    var task2Res = await task2(task1Res);
    // task 3 호출
    var task3Res = await task3(task2Res);
}

 

위와 같이 task를 호출할 때마다 await을 걸어주고 response 된 결과 값을 받아 다음 task로 넘겨주도록 구성을 하였습니다.

async와 await을 사용하지 않았다면 위의 코드에서는 response 값이 넘어오지만 sync가 맞지 않기 때문에 다음 task 함수로 전달해 줄 값을 찾지 못하고 undefined로 넘겨주게 됩니다. 그래서 예제와 같이 async와 await을 간단하게 사용해서 sync를 맞춰줬다고 이해하시면 됩니다.

 

그럼 실행 결과 화면을 볼까요?


실행 결과

실행 결과처럼 sync가 돼서 task별로 순차적으로 결괏값을 받아 다음 task로 전달해 줘서 결괏값이 정상적으로 출력됐습니다.

 

그러면 이번엔 task별로 시간 지연을 시켜서도 순차 처리가 되는지 확인해 보도록 하겠습니다.

 

반응형

예제 2

<script>
/**
 * Document load 
 */
document.addEventListener('DOMContentLoaded', () => {

    test();
});

/**
 * Task 별 Promise async 처리 및 순차 처리를 위한 await 사용
 */
async function test () {
    
    // 초기 인자 설정
    var initObj = {
        index : 1,
        text : 'Task',
    };

    // task 1 호출
    var task1Res = await task1(initObj);
    // task 2 호출
    var task2Res = await task2(task1Res);
    // task 3 호출
    var task3Res = await task3(task2Res);
}

/**
 * 1번 Task Function
 */
async function task1 (preObj) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(preObj.text + ' ' + preObj.index++);
            resolve(preObj);
        }, 1000);
    });
}

/**
 * 2번 Task Function
 */
async function task2 (preObj) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(preObj.text + ' ' + preObj.index++);
            resolve(preObj);
        }, 2000);
    });
}

/**
 * 3번 Task Function
 */
async function task3 (preObj) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(preObj.text + ' ' + preObj.index++);
            resolve(preObj);
        }, 3000);
    });
}
</script>

task 함수별로 promise 내에서 setTimeout() 함수를 사용하여 시간 지연을 시켜줬습니다.

- task1 1초 지연
- task2 2초 지연

- task3 3초 지연 

 


실행 결과

setTimeout()을 이용하여 시간 지연을 시킨 결과 순차적으로 호출되는 모습입니다.

 


마무리

오늘은 자바스크립트의 async와 await에 대해 간단한 예제를 통해 알아봤습니다. 앞의 콜백지옥과 프로미스 관련 글을 먼저 보셨다면 오늘 async, await에 대해 좀 더 쉽게 이해하실 수 있으셨을 겁니다! 자바스크립트의 콜백지옥을 벗어나기 위해 프로미스가 나오고, 그 프로미스도 조금 더 수월하게 처리하기 위해 async, await가 나오게 됐습니다. 하지만 무조건 그 전의 문제를 해결하기 위해 나왔다고 해서 좋다는 것은 아닙니다. 각각의 특징과 차이를 이해하고 있다면 적용할 업무에 따라 단순하게 콜백처리를 해도 되고, 프로미스 처리를 해도 되고, 복잡도가 높은 경우는 async, await를 사용하시면 됩니다. 프로그래밍에 정답은 없으니까요! 

 

 

 

그럼 오늘도 저의 작고 소중한 글을 읽어주셔서 감사합니다. :)

 

 

 


 

반응형