async & await

junhyeok·2021년 4월 25일
0

async & await란?

async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법입니다. 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완했습니다.
async와 aswait라는 특별한 문법을 사용하면 프로미스를 좀 더 편하게 사용할 수 있습니다.

async function

function 앞에 async를 붙이면 해당 함수는 항상 프로미스를 반환합니다.
프로미스가 아닌 값을 반환하더라도 이행 상태의 프로미스로 값을 감싸 이행된 프로미스가 반환되도록 합니다.

async function f(){
	return 1; 
}
f().then(alert); // result가 1인 이행 프로미스가 반환.
  • 프로미스가 아닌 값을 반환하더라도 이행 상태의 프로미스로 값을 감싸 이행된 프로미스가 반환되는 예.

# 정리. async가 붙은 함수는 반드시 Promise를 반환하고, Promise가 아닌 것은 Promise로 감싸 반환합니다.

await function

자바스크립트는 await 키워드를 만나면 Promise가 처리될 때까지 기다립니다.
결과는 그 이후 반환됩니다.

async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 5000)
  });
  let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)
  alert(result); // "완료!"
}
f();		

함수를 호출하고, 함수 본문이 실행되는 도중에 (*)로 표시한 줄에서 실행이 잠시 '중단'되었다가 프로미스가 처리되면 실행이 재개됩니다. 이때 Promise 객체의 result 값이 변수 result에 할당됩니다.
따라서 위 예시대로 실행하면 5초 뒤에 '완료!'가 출력됩니다.

Promise가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU리소스가 낭비되지 않습니다.

*주의

일반함수엔 await를 사용할 수 없습니다. async 함수가 아닌데 await를 사용하면 문법 에러가 발생합니다. function 앞에 async를 붙이지 않으면 이런 에러가 발생할 수 있습니다.

async & await 예제

fetchUser(), fetchTodo() 함수들을 실행하면 각각 사용자 정보와 할 일 정보가 담긴 프로미스 객체가 반환됩니다.
두 함수를 이용하여 할 일 제목을 출력해보겠습니다.

예제 코드의 로직은 말해보자면,
1. fetchUser()를 이용하여 사용자 정보 호출
2. 받아온 사용자 아이디가 1이면 할 일 정보 호출
3. 받아온 할 일 정보의 제목을 콘솔에 출력

function fetchUser() {
  var url = 'https://jsonplaceholder.typicode.com/users/1'
  return fetch(url).then(function(response) {
    return response.json();
  });
}

function fetchTodo() {
  var url = 'https://jsonplaceholder.typicode.com/todos/1';
  return fetch(url).then(function(response) {
    return response.json();
  });
}

async function logTodoTitle() {
  var user = await fetchUser();
  if (user.id === 1) {
    var todo = await fetchTodo();
    console.log(todo.title); // delectus aut autem
  }
}

async & await 예외처리

async & await에서 예외를 처리하는 방법은 try catch 입니다.
코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류 까지도 catch로 잡아낼 수 있습니다. 발견된 에러는 error 객체에 담기기 때문에 에러의 유형에 맞게 에러코드를 처리하면 됩니다.

async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); // delectus aut autem
    }
  } catch (error) {
    console.log(error);
  }
}

참고 링크

profile
Developer

0개의 댓글