[javascript] async / await

Chan의 기술 블로그·2025년 11월 14일

javascript

목록 보기
8/8

이 글은 『자바스크립트 딥 다이브』를 공부하며 정리한 내용입니다.

async / await란?

ES8(ECMAScript 2017)에서 도입된 async/await는 프로미스를 기반으로 하며, 비동기 코드를 마치 동기 코드처럼 작성할 수 있게 해주는 문법이다.

기존에는 비동기 처리 후속 작업을 then, catch에 콜백 형태로 전달해야 했지만 async/await를 사용하면 후속 처리 메서드 없이 자연스러운 흐름으로 비동기 코드를 작성할 수 있다.

async 함수

  • async 함수는 반드시 Promise를 반환한다.
  • 반환값이 일반 값이어도 자동으로 Promise.resolve(반환값) 형태로 감싸져 반환된다.
  • constructor는 async가 될 수 없다.
// async 함수 선언문
async function foo(n) {return n};
foo(1).then(v => console.log(v)); // 1

// async 함수 표현식
const bar = async function(n) {return n};
bar(2).then(v => console.log(v)); // 2

// async 화살표 함수
const baz = async n => n;
baz(3).then(v => console.log(v)); // 3

// async 메서드
const obj = {
	async foo (n) {return n};
};
obj.foo(4).then(v => console.log(v)); // 4

// async 클래스 메서드
class MyClass {
	async bar (n) {return n};
}
const myClass = new MyClass();
myClass.bar(5).then(v => console.log(v)); // 

await 키워드

  • await는 프로미스가 settled(fulfilled 또는 rejected) 될 때까지 기다린다.
  • fulfilled되면 resolve 값이 반환되고, rejected 되면 에러가 던져진다.

잘못된 사용 예

모든 비동기 처리에 await를 걸면 불필요한 “순차 실행”이 일어난다.

올바른 병렬 처리 예

async function foo() {
	const res = awite Promise.all([
    	new Promise(resolve => setTimeout(() => resolve(1), 3000)),
      	new Promise(resolve => setTimeout(() => resolve(2), 2000)),
      	new Promise(resolve => setTimeout(() => resolve(3), 1000)),
    ]);
  
  	console.log(res); // [1, 2, 3]
}

foo();

순차 실행이 필요한 경우

async function foo() {
	const a = await new Promise(resolve => setTimeout(() => resolve(1), 3000));
	const b = await new Promise(resolve => setTimeout(() => resolve(a + 1), 2000));
	const c = await new Promise(resolve => setTimeout(() => resolve(b + 1), 1000));
  
  	console.log(res); // [1, 2, 3]
}

foo();

이처럼 앞선 결과가 다음 로직에 필요하다면 순차 실행해야 한다.


에러 처리

async/await에서는 try ... catch를 사용해 동기 코드와 동일한 방식으로 에러를 처리할 수 있다.

const foo = async () => {
	try {
    	const wrongUrl = 'https://wrong.url';
      	const res = await fetch(wrongUrl);
      	const data = await res.json();
      	console.log(data);
    } catch(err) {
    	console.log(err);
    }
};
foo()

try 블록 내부에서 발생한 모든 에러(네트워크 에러 포함)를 catch가 잡는다.

또한 async 함수에서 catch를 생략하면, 해당 async 함수는 reject 상태의 프로미스를 반환하기 때문에 .catch() 메서드로 에러 처리도 가능하다.

const foo = async () => {
	const wrongUrl = 'https://wrong.url';
    const res = await fetch(wrongUrl);
    const data = await res.json();
    return data;
};
foo().then(console.log).catch(console.error);
profile
퍼블리셔에서 프론트앤드로 전향하기

0개의 댓글