본문 바로가기
JavaScript

[자바스크립트] async & await

by 메이플 🍁 2022. 11. 20.

async & await

  • 비동기 처리방식인 콜백함수와 프로미스의 단점을 보완하기 위해 최근에 나온 자바스크립트의 비동기 처리 문법을 말한다
  • 콜백함수가 여러번 사용되면 콜백 지옥이 발생한다 → 프로미스의 등장
  • 프로미스가 여러번 체이닝(중첩)이 되면 콜백 지옥과 같은 문제점이 발생한다 → async & await을 사용해서 마치 동기적으로 코드가 진행되는 것처럼 사용
  • 함수 앞에 async라는 키워드를 붙여주면 함수 블럭 안에 있는 코드가 자동으로 프로미스를 사용하는 것처럼 변환이 되어진다
  • async라는 키워드가 붙은 함수내에서만 await을 사용할 수 있다

 

기본문법

async function 함수명() {
  await 비동기처리메서드명();
}
  1. 비동기로 처리하고 싶은 함수 앞에 async라는 예약어를 붙인다
  2. 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await await를 붙인다

 

Promise에서 발생되는 문제점을 해결하기 위한 async와 await

비동기적으로 처리하고 싶은 함수에 키워드 async를 붙여주면 블락 안에 있는 코드가 Promise화 된다.

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000);
  return '🍎';
  throw 'error';
}

async function getBanana() {
  await delay(1000);
  return '🍌';
}

Promise 사용시

Promise도 중첩적으로 사용하면 콜백지옥과 같이 가독성이 떨어진다.

function pickFruits() {
  return getApple().then(apple => {
    return getBanana().then(banana => `${apple} + ${banana}`)
  });
}

pickFruits().then(console.log);

async & await 사용시

async라는 키워드를 함수 앞에 붙여서 해당 함수를 promise화 시켜준다. await라는 키워드는 async 함수 안에서만 쓰일 수 있다.

async function pickFruits() {
  const apple = await getApple();
  const banana = await getBanana();
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

 

try, catch 구문

async함수에서 에러처리시 사용하는 try, catch구문. try에서 비동기적으로 처리한 값을 받아오지 못할경우 catch에서 에러를 받는다.

async function pickFruits() {
  try {
    const apple = await getApple();
    const banana = await getBanana();
  } catch() {
    cosnsole.log('Error')
  }
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

 

await 병렬처리

기존 코드의 문제점: getApple()과 getBanana() 함수는 값을 받아오는데 각각 1초씩 소요되어 모든 코드를 가져오는데 총 2초의 시간이 걸린다. 코드가 서로를 기다릴 필요가 없으므로 1초의 시간이 낭비가 된다

async function pickFruits() {
  const apple = await getApple(); // 1초
  const banana = await getBanana(); // 1초
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

await 병렬처리

async function pickFruits() {
  const applePromise = getApple(); // 값을 가져온다
  const bannaPromise = getBanana(); // 값을 가져온다
  const apple = await applePromise;
  const banana = await bannaPromise;
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

 

일반함수 vs promise vs async & await

일반함수 (동기적)

function fetchItems() {
  var items = [1, 2, 3];
  return items
}

console.log(fetchItems())

setTimeout (비동기적)

특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리다. fetchItems 함수를 실행했지만 setTimeout의 결과값을 기다려주지 않으므로 undefined가 출력된다.

function fetchItems() {
  setTimeout(() => {
    var items = [1, 2, 3];
    return items
  }, 3000);
}

console.log(fetchItems())

콜백함수 (비동기적)

콜백을 사용하면 특정 로직이 끝났을때 원하는 동작을 실행시킬 수 있다.

function fetchItems(print, timeout) {
  setTimeout(print, timeout);
}

fetchItems(() => {
  var items = [1, 2, 3];
  console.log(items)
}, 3000)

promise (비동기적)

function fetchItems() {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      var items = [1, 2, 3];
      resolve(items)
    }, 3000);
  });
}

function logItems() {
  fetchItems().then(items => {
    console.log(items);
  })
}

logItems();

async & await (비동기적)

function fetchItems() {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      var items = [1,2,3];
      resolve(items)
    }, 3000);
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems);
}

logItems();

 


 

Reference

댓글