FrontEnd/JavaScript

[JavaScript] async & await 개념 및 활용

데브슈 2025. 3. 25. 00:49

이전 비동기 프로그래밍을 다룰 때 콜백함수, 프로미스를 사용하면서 코드가 복잡해지면서 가독성이 떨어지는 문제가 발생했다.

이를 해결하기 위해 async / await 등장했다.

 

async/await 에 대해 들어가기 전 비동기 프로그래밍이란 무엇인지부터 알아보도록 하자.


1. 비동기 프로그래밍?

한 번에 하나의 작업만 수행하는 동기적인 코드와 달리 시간이 걸리는 작업(네트워크 요청 etc)을 기다리는 동안

다른 작업을 실행할 수 있도록 하는 방식


2. async/await ?

 1) async

함수 앞에 붙으며 해당 함수가 항상 Promise를 반환하다록 만듦

함수 내 await 키워드 사용 가능

 

 2) await

Promise가 처리될 때까지 기다렸다가 결과값 반환

async 함수 내부에서만 사용 가능

안쪽에 실행되는 함수가 무조건 Promise 이어야 async, await가 작동한다.

→ resolveFunc1() 이 만약 promise 가 아닐 경우 func1() 의 await 에 문제가 발생한다.

 

정리하자면

함수 전체에 타깃을 지정하여 async를 설정한다. →해당 function 내 모든 비동기 function 을 동기 동작 선언 (직렬화)

즉, 로직 자체를 promise.then으로 전부 묶어버리는 것이다.

 

그렇다면 왜 사용하냐?

(1) Promise.then() 체이닝보다 코드 직관적이기에 이해하기 쉬우며,

(2) try...catch를 사용하여 일반적인 동기 코드처럼 예외를 처리할 수 있어 에러 핸들링에 용이하고

(3) 콜백 중첩 대신 await 사용하여 순차적인 코드 작성이 가능하여 콜백 지옥 방지가 가능하다.

단, async/await 는 promise를 대체하기 위한 기능이 아닌 유지보수가 뛰어나도록 하는 것 뿐이다.

내부적으로는 Promise를 사용하여 비동기 처리를 해야 한다.


3. async/await 활용

예시 코드를 보면 async/await의 경우 await 키워드를 통해 비동기 처리를 하고 있음을 알 수 있다.

async 함수 내부에서 await가 여러 개 있을 경우, 위에서부터 아래로 순차적으로 실행

 

참고로 resolve비동기 작업이 끝났음을 알리는 신호로 없을 경우, 계속 pending 상태에 있기 때문에

다음 함수로 넘어가지 않는다.

 

이처럼 비동기적 접근 방식을 동기적으로 작성 가능하도록 하여 코드 가독성을 높여 유지보수를 용이하게 해준다.

function func1(num, sec) {
retrun setTimeout(() =>{
	console.log(num);
}, sec);

만약 func1() 을 위처럼 promise 선언없이 쓴다면 처리가 완료된 대로 실행된다.  


4. async/await 활용 방법 → 병렬 처리

await을 사용하면 개별 비동기 작업이 순차적으로 실행되어 코드가 동기적으로 수행되는 것처럼 보인다. 하지만 이를 변수에 저장하여 Promise.all()과 같은 방식으로 병렬 처리하면 모든 작업이 완료될 때까지 기다려야 하므로 실행 시간이 더 길어질 수 있다.

 

만약 순서가 중요하지 않다면 각 프로미스 객체를 생성한 후 Promise.all()을 사용하여 병렬처리를 하거나 개별 프로미스 결과를 변수에 저장한 후 await를 통해 값을 꺼내는 방법을 사용할 수 있다.

function getSu(){
	return new Promise( (resolve, reject) => {
    setTimeout(() => resolve("su"), 1000);
})
}

function getNing() {
	return new Promise( (resolve, reject) => {
    setTimeout(() => resolve("ning"), 1000);
    })
}

예시 코드를 Promise.all 메소드를 통해 병렬처리해보도록 하겠다.

async function getNickname(){
	const [a, b] = await Promise.all([getSu(), getNing()]);
    
    console.log(`${a}${b}`)
}

getNickname();

→ 출력 값: suning

 

Promise.all() 은 배열 인자의 각 프로미스 비동기 함수들이 resolve가 모두 되어야 결과를 리턴 받는다.

배열 인자의 각 프로미스 함수들은 제각각 비동기 논블록킹으로 실행되어 시간 단축이 가능하다. 참고로 리턴값은 각 프로미스 함수의 반환값들이 배열로 담겨져 있다.

 

정리하자면 promise.all은 여러 개의 작업 동시 실행(병렬)이 가능하기 때문에 각 작업이 끝날 때까지 기다리지 않고 병렬(동시) 실행되므로 전체 실행 시간이 줄어든다.

 

'FrontEnd > JavaScript' 카테고리의 다른 글

[JavaScript] Fetch API 란?  (0) 2025.04.02
[JavaScript] Promise 란?  (0) 2025.03.23
[JSON] JSON 이란? 개념과 사용 방법  (0) 2025.03.22