Server/NodeJS

[JavaScript] async와 await란?

백엔드 규니 2020. 6. 25. 14:22
728x90
반응형

async와 await는 자바스크립트의 비동기 처리 패턴 중 최근에 나온 문법이다. 자바스크립트는 싱글스레드 기반 언어이기 때문에 비동기 처리가 필수적이다. 비동기 처리는 결과를 예측할 수 없기 때문에 동기식의 처리가 필요하다. 대표적으로 앞에 글에서 작성했던 것처럼 promise, callback이 있다. async와 await는 기존 동기식 처리의 단점을 보완하고 가독성을 높혀주는 코드를 작성할 수 있다. 

먼저 다시 한번 자바스크립트의 비동기처리에 대해서 얘기하고 가려 한다.

let first = 10;
let second = 20;
let result = 0;

function add(x, y) {
    return x + y;
}

setTimeout(() => {
    result = add(first, second);
    console.log(result)
}, 1000);

first = 20;
40

위의 결과는 30이 나올 것 같지만, 40이 나오게 된다. 이유가 무엇일까? 

 

자바스크립트는 작업을 큐에 넣고 순서대로 작업을 하게 된다. 이 때 작업이 큐에 들어가게 되는 과정에 대한 이해가 필요하다. 최초의 작업은 스크립트 파일이다. 그리고 그 다음에는 setTimeout()이 작업으로 큐에 들어가게 된다. 그래서 첫 번째 스크립트 파일이 완료된 후에 setTimeout() 함수가 실행이 된다. 따라서 스크립트 파일의 처음에는 first = 10 이었지만 마지막에는 first = 20이 되기 때문에 결과값으로는 40이 찍히게 된다. 이러한 상황을 처리하기 위해서 하는 작업이 동기식 처리인 promise, callback이 있었다고 정리했었다. 이번에는 promise와 async, await에 대해서 정리해보려 한다.

 

 

async & await

async는 promise의 코드를 깔끔하게 줄여주기 때문에 가독성을 높혀주는 효과가 있다. 사용법은 function 앞에 async만 붙여주면 되고 비동기로 처리되는 부분 앞에 await만 붙여주면 된다. 그리고 한가지 알아둬야 할 점은 await 뒤에 오는 부분은 반드시 promise를 반환해주어야 하고, async가 붙은 function도 promise를 반환해야 한다는 점이다. 사용법의 예시는 아래와 같다. 

async function test() {
    // logic
}

변수 = async() => {
	// logic
}

그러면 이번에는 promise와 async & await를 사용했을 때 어떤 차이가 있는지를 알아보자.

let asyncFunc1 = (msg) => {
    new Promise((resolve) => {
        setTimeout(() => {
            resolve(`func1 : ${msg}`);
        }, 1000);
    })
};

let asyncFunc2 = (msg) => {
    new Promise((resolve) => {
        setTimeout((resolve) => {
            resolve(`func2 : ${msg}`);
        }, 1000)
    })
}

위와 같이 promise를 반환하면 함수 2개가 있다고 가정하자. 아래는 promise를 썼을 때의 예시이다.

function promiseMain() {
    asyncFunc1('Hello').then((result) => {
        console.log(result);
        return asyncFunc2('world')
    }).then((result) => {
        console.log(result);
    })
}

이번에는 async & await를 사용하였을 때의 코드이다.

async function asyncMain() {
    let result = await asyncFunc1('Heello');
    console.log(result);
    result = await asyncFunc2('world');
    console.log(result);
}

이렇게 짧은 코드로만 비교하여도 확실히 async & await을 사용하는 것이 promise보다 가독성이 좋다는 것을 알 수 있다. 

 

async & await 예제

function asyncItem() {
    return new Promise((resolve, reject) => {
        var item = [1, 2, 3];
        resolve(item);
    });
}

async function logItems() {
    var resultItem = await asyncItem();
    console.log(resultItem);
}

asyncItem 함수는 Promise()를 객체를 반환하는 함수이다. resolve() 함수를 사용했기 때문에 item 배열을 반환해야 한다. 만약 await를 사용하지 않고 promise(), then()을 사용해야 하는데 이거를 비동기적 사고를 하면서 코드를 작성해야 하고 코드가 좀 길어진다면 가독성도 떨어지고 머리도 아플 것이다. 

 

 

 

async & await 예외 처리

async & await에서 예외를 처리하는 방법은 try ~ catch이다. 프로미스에서 예외 처리를 위해 .catch()를 이용했던 것처럼 async에서는 catch { } 를 이용하면 된다. 

async function test() {
    try {
        var user = await fetchUser();
        if (user.id === 1) {
            var todo = await fetchTodo();
            console.log(todo.title);
        }

    } catch(err) {
        console.log(error);
    }
}

 

 

Reference

https://joshua1988.github.io/web-development/javascript/js-async-await/

https://blueshw.github.io/2018/02/27/async-await/

반응형