[JS] async & await

Minyoung's Conference·2022년 6월 21일
1

JavaScript

목록 보기
15/28
post-thumbnail

Promise를 더 쉽고 가독성 좋게 쓸 수 있는 async와 await에 대해 알아보자.
먼저 async이다.

//async

function hello() {
  return 'hello';
}

async function helloAsync() {
  return 'hello Async';
}

위의 함수는 일반적으로 우리가 아는 함수이고 아래에는 async 라는 키워드가 붙어있다.
그리고 그 함수에 마우스를 가져다 올려보면, Promise를 반환한다는 것을 알 수 있다.

그렇다면 두 함수 모두 콘솔을 찍어보자.

function hello() {
  return 'hello';
}

async function helloAsync() {
  return 'hello Async';
}

console.log(hello());
console.log(helloAsync());

아래 helloAsync함수의 반환값이 Promise인 것을 확인할 수 있다.
왜냐하면, helloAsync 함수 Promise를 반환하는 것을 확인했고,
콘솔창에 helloAsync 함수를 호출했기 떄문이다.
Promise를 출력하면 Promise 객체 그대로 출력이 된다.
(helloAsync()는 Promise이다.)

이를 통해,

async 키워드를 붙여주게 되면, Promise를 반환하는 비동기처리 객체가 된다는 것을 알 수 있다.

그렇다면, Promise를 반환하기 때문에 helloAsync() 뒤에 then을 바로 붙여줘도 된다는 뜻이 아닐까? 확인해보자.

function hello() {
  return "hello";
}

async function helloAsync() {
  return "hello Async";
}

helloAsync().then((res) => {
  console.log(res);
});

// 결과 : hello Async

res(resolve)에 hello Async 가 들어오는 것을 알 수 있다.
res에 hello Async 가 전달되어 콘솔에 출력되었다.
res는 async function의 return값에서 왔다.

async가 붙은 함수의 Return값은 비동기작업 객체인 Promise의 resolve의 결과값이 된다.
그러니 async만 붙이고 return만 해도 promise를 리턴하면서 resolve를 return안의 값과 똑같은 효과를 얻는다고 생각하면 된다. 그래서 hello Async의 값이 res에 들어오게 되는 것이다.

정리하자면, async는 함수에 붙어서 promise를 반환하게 만드는 것이다.

이제 await을 알아보자.

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

delay라는 함수를 만들었다. setTimeout함수 내에 resolve를 수행하는 코드만 존재하는 경우, 더 축약해서 사용할 수 있다.

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

콜백함수 자체로 전달한 축약형은 위와 같다.
이제 delay 함수를 이용해서 3초뒤에 특정 동작을 할 수 있도록 async함수를 바꾸어보자.

async function helloAsync() {
  return delay(3000).then(() => {
    return "hello Async";
  });
}

위와 같이 바꿀 수 있다.


then의 결과값이 return 뒤의 "hello Async"이며, 3초뒤에 작동해 helloAsync함수의 결과값으로 반환되는 것을 알 수 있다.

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

async function helloAsync() {
  return delay(3000).then(() => {
    return "hello Async";
  });
}

helloAsync().then((res) => {
  console.log(res);
  
// 결과 : (3초뒤) hello Async
});

그리고 async 함수이기에 then 메소드를 이용해 helloAsync함수를 다시 then을 이용해 불러주어야한다. 우리는 3초기다렸다가 반환하면 되는 간단한 기능을 구현하고 있다. 그에 비해, 코드가 길다고 느껴질 수 있다. 이럴 때 await을 이용한다. 만들어보자.

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

위와 같이 표현할 수 있다.
await이라는 키워드를 비동기 함수호출 앞에 붙이게 되면
비동기 함수가 동기적인 함수처럼 작동하게 된다. 즉,
await 키워드가 붙은 함수 호출은 await 뒤에 있는 함수가 끝나기 전까지
그 아래 코드가 작동되지 않음을 의미한다. (await 키워드가 있는 줄은 동기적으로 실행) 그리고 await 키워드는 async가 붙어있는 함수 내에서만 사용가능하다.

그러면, helloAsync() 의 결과값도 await을 이용해 불러와보자.

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

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

async function main() {
  const res = await helloAsync();
  console.log(res);
}
main();

// 결과 : (3초뒤) hello Async

Promise를 쉽게 쓰기 위한 async와 동기적으로 사용할 수 있는 방법인 await까지 배워보았다.

profile
안녕하세요, FE 개발자 김민영입니다.

0개의 댓글