async await

BirdsOnTree·2022년 7월 28일
0

Javascript

목록 보기
6/17
post-thumbnail

async/await 문법은 ES8에 해당하는 문법으로서, Promise 를 더욱 쉽게 사용 할 수 있게 해준다.

자바스크립트는 싱글 스레드 프로그래밍언어기 때문에 비동기처리가 필수적이다. 이러한 기법으로는 setTimeout, callback, promise가 있다.

사용법

1. async는 function 앞에 위치한다.

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

async function f() {
  return 1;
}

f().then(alert); // 1

2. async 함수 안에는 키워드 await이 있다.

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

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)

  alert(result); // "완료!"
}

f();

함수를 호출하고, 함수 본문이 실행되는 도중에(*)로 표시한 줄에서 실행이 잠시 '중단’되었다가 프라미스가 처리되면 실행이 재개된다.
위 예시를 실행하면 1초 뒤에 '완료!'가 출력됩니다.

await는 말 그대로 프라미스가 처리될 때까지 함수 실행을 기다리게 만든다. 프라미스가 처리되면 그 결과와 함께 실행이 재개된다.

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

await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법이다. promise.then보다 가독성 좋고 쓰기도 쉽다.

3. await는 최상위 레벨 코드에서 작동하지 않는다.

// 최상위 레벨 코드에선 문법 에러가 발생함
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();

하지만 익명 async 함수로 코드를 감싸면 최상위 레벨 코드에도 await를 사용할 수 있습니다.

// 최상위 레벨 코드에선 문법 에러가 발생함
(async () => {
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();
  ...
})();

4. 애러 핸들링

프라미스가 정상적으로 이행되면 await promise는 프라미스 객체의 result에 저장된 값을 반환한다. 반면 프라미스가 거부되면 마치 throw문을 작성한 것처럼 에러가 던져진다.

async function f() {
  await Promise.reject(new Error("에러 발생!"));
}

//or

async function f() {
  throw new Error("에러 발생!");
}

실제 상황에선 프라미스가 거부 되기 전에 약간의 시간이 지체되는 경우가 있다. 이런 경우엔 await가 에러를 던지기 전에 지연이 발생된다.

이때 try..catch를 사용해 잡을 수 있습니다.

async function f() {

  try {
    let response = await fetch('http://유효하지-않은-주소');
    let user = await response.json();
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();

에러가 발생하면 제어 흐름이 catch 블록으로 넘어간다.

그렇다고 async/await가 Promise를 완벽히 대체하는 것이 아니다.
비동기는 Promise객체로 처리하고 async/await는 비동기를 동기식으로 처리하는 기법이다.

0개의 댓글