반원 블로그

1회차 - 05 ES6 문법 - Async, Await 본문

2018~/react native

1회차 - 05 ES6 문법 - Async, Await

반원_SemiCircle 2020. 6. 30. 17:51

Async, Await

기존 javascript의 콜백 지옥 문제를 해결해준 문법이다.

과거 비동기식 함수 호출의 경우 콜백시킬 함수를 받아서 이를 실행시켜주기 때문에 [콜백할 함수를 서버에서 받는다->실행]을 반복하게 된다.

callback=>{
  callback=>{
    callback=>{
      callback=>{return data;}
    }
  }
}

이제 Async, Await를 배워본다.
먼저 함수 하나를 만든다. 이 때 기존에 있는 Promise 객체(함수)를 이용할 건데, 이것의 콜백리턴으로 resolvereject가 들어온다. 이를 이용해보자.

function resolvePromise() {
  return new Promise((resolve, reject) => {

  });
}

Promise 함수는 콜백인 resolve를 실행해야 끝나는 함수인데, 이를 setTimeout으로 딜레이 실행을 하도록 구현한다.

function resolvePromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('done!!');
    }, 2000);
  });
}

이렇게 resolvePromise()함수를 만들었으면, 이 함수를 사용하는 함수를 또 만들어본다. 이 때 async를 사용한다.

function resolvePromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('done!!');
    }, 2000);
  });
}

async function getPromise1() {

}

async 함수를 만들어야 await 를 사용할 수 있다.
await 를 "기다려준다"로 이해하고 있으며 된다.

const result = await resolvePromise();
이렇게 작성하면 resolvePromise함수가 끝날 때까지 기다려준 뒤 결과를 result에 저장된다.

// async & await
function resolvePromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('done!!');
    }, 2000);
  });
}

async function getPromise1() {
  const result = await resolvePromise();
  console.log(result);
}

getPromise1();

출력 결과

=> Promise {}
done!!

여러 개를 호출해보자.

function resolvePromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('done!!');
    }, 2000);
  });
}

async function getPromise1() {
  const result = await resolvePromise();
  console.log(result);
  await resolvePromise();
  console.log(`2`);
  await resolvePromise();
  console.log(`3`);
  await resolvePromise();
  console.log(`4`);
  await resolvePromise();
  console.log(`5`);
}

getPromise1();

출력결과

=> Promise {}
done!!
2
3
4
5

이렇게 특정 함수가 끝날 때까지 기다려주는 문법이 async await이다.

응? 당연한 거 아니야? 당연히 위 함수 실행 기다리고 아래 코드로 넘어가는 거 아니야?

파이썬과 같이 한줄씩 번역하는 인터프리터는 이것이 당연하다.

print("a")
print("b")
print("c")

그러나 자바스크립트의 경우는 조금 다르다.

for (var i = 0; i < 3; i++) {
    setTimeout(function() {alert(i); }, 1000);
}

하면 당연이 alert창이 1,2,3이 뜰 것 같은데, 왜인지 3,3,3이 뜬다.
javascript 엔진이 먼저 코드를 실행후 비동기로 동작하는 setTimeout Web API 를 3번 실행 하였기 때문에 현재 Event Queue에는 3개의 Event Handler가 들어가있다.
그래서 모든 코드 실행 후 마지막으로 Event Queue에 등록된 Event Handler 가 처리가 되기 때문에 현재 for 문의 i 값이 3임으로 실행되는 Event handler는 3을 3번 출력 하는 것이다.

쉽게 정리하면 자바스크립트는 기본적으로 기다린다라는 개념이 없다. 그래서 다른 함수에서 그 흔한 delay나 sleep함수가 없고, 예약하는 setTimeout함수들이 존재한다. 자바스크립트 코드가 순서대로 실행되는 걸 눈으로 볼 수 없다는 것이다.

때문에 오류가 나는 코드가 중간에 있을 경우

  • 파이썬 : 도중에 에러가 발생한다.
  • 자바스크립트 : 아예 실행이 안된다. 이전 출력(console.log)가 안나오는 이유가 이것.

때문에 함수가 순차적으로 실행할 필요가 있을 경우 callback을 이용해야하는데, 이를 너무 많이 사용하게되니
ES6에서 나온 것이 async, await 이다.

Comments