JS 비동기패턴 async & await

고은정·2021년 4월 10일
1

개발포스팅

목록 보기
3/20
post-thumbnail
post-custom-banner

async? await?

자바스크립트의 비동기 패턴입니다.

문법배우기

async function start() {
  let hello = () => {
    setTimeout(() => console.log("hello"), 5000);
  };
  let result = await hello(); // hello가 종료될 때 까지 기다림(비동기)
  result;
}

start();

한눈에 봐도 이해될 정도로 사용법은 매우 쉽습니다.

그 전에! Promise!!

async와 await를 이해하기 위해서는 Promiss 객체에 대한 이해가 필요합니다. MDN에서 설명하는 Promiss객체에 대한 간단한 설명은 다음과 같습니다.

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
...프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하지는 않고, 대신 프로미스를 반환해서 미래의 어떤 시점에 결과를 제공합니다...

Promise는 아래의 상태를 가집니다.

  • 대기(pending): 이행하거나 거부되지 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

async

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

await

await는 프라미스가 처리될 때 까지 기다립니다. 기다리는 동안에 다른 스크립트나 이벤트 처리는 계속해서 동작하기 때문에 CPU리소스는 낭비되지 않습니다.
await를 사용하기 위해서는 아래와 같은 규칙을 지켜야 합니다.

  1. 반드시 async 함수 내에 작성합니다.

  2. 최상위 레벨 코드에서는 동작하지 않습니다. 👉 async 함수 내에 작성하면 동작!

// 아래와 같은 최상위 레벨에서는 동작X
let response = await fetch('/test.json');
let user = await response.json();
  1. 'thenable'객체를 받습니다.
    thenable 객체는 서드파티 객체가 프라미스가 아니지만 프라미스와 호환 가능한 객체를 제공할 수 있다는 점에서 생긴 기능입니다.

  2. 메서드 이름 앞에 async를 추가하면 async 클래스 메서드를 선언할 수 있습니다.

class Waiter {
  async wait() {
    return await Promise.resolve(1);
  }
}

new Waiter()
  .wait()
  .then(alert); // 1

예제!

async & await의 목적에 맞게 비동기를 위해서 사용되는데요, 사용했을 때와 사용하지 않았을 때 차이를 예제를 통해서 확인하겠습니다. 간단한 예제를 위해, 위의 문법배우기에서 사용한 예제를 재활용 하겠습니다.

async & await 사용

async function start() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 5000);
  });

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

  console.log(result);
  console.log("맨 마지막에 출력되면 좋겠다");
}

start();

사용O 결과

async & await 사용X

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

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

  console.log(result);
  console.log("맨 마지막에 출력되면 좋겠다");
}

start();

사용X 결과

참고

profile
개발이 하고싶어요
post-custom-banner

0개의 댓글