ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] async와 await란?
    Server/NodeJS 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/

    반응형

    댓글

Designed by Tistory.