상세 컨텐츠

본문 제목

코드카데미 Javascript - Async Await

IT/Javascript

by J KIMS 2020. 10. 12. 16:45

본문

반응형

 

 

Async Await

  • 비동기 처리를 위한 문법 (프로미스의 상위 버전이란 느낌)

  • 가독성과 확장성을 향상시킴

  • syntactic sugar


Async 사용법

💡 async는 그 함수가 비동기적임을 나타내는 키워드이다.

 

다음처럼 function declaration 앞에 async를 쓰거나

 

async function myFunc() {
  // Function body here
};

myFunc();

 

function expression도 async로 만들 수 있다 

 

const myFunc = async () => {
  // Function body here
};

myFunc();

 

 

async 함수는 항상 프로미스를 리턴한다

따라서 .then()이나 .catch같은 기존 프로미스 문법을 쓸 수 있음

 

  • 함수에서 리턴된 것이 없다면 resolved value로써 undefined를 가진 프로미스를 리턴함

  • 함수에서 프로미스가 아닌 값이 리턴되면, async는 그 값을 resolved value로 하는 프로미스를 리턴함

  • 함수에서 프로미스가 리턴되면 그게 리턴값이 됨

예시

 

async function fivePromise() { 
  return 5;
}

fivePromise()
.then(resolvedValue => {
    console.log(resolvedValue);
  })  // Prints 5

await 연산자

 

async는 그 자체로 위력을 발휘하기 보단 await와 함께 쓰이는 경우가 많다.

 

  • awiat는 async 함수 안에서만 사용가능한 연산자이다.

  • promise의 resolved value를 리턴한다.

  • 프로미스가 완료될 때까지 async 함수를 잠깐 멈추는 역할을 함

async function asyncFuncExample(){
  let resolvedValue = await myPromise();
  console.log(resolvedValue);
}

asyncFuncExample(); // Prints: I am resolved now!

 

예를 들어 위 코드에서 myPromise()는 "I am resvoled now!"라는 문자열을 갖는 프로미스 함수이다.

 

여기서 await는 resolvedValue에 값이 할당될때까지 다음 코드가 실행되지 않게 한다. (마치 synchronous code 처럼)

만약 await가 없다면 프로미스가 실행되는 도중에 console.log가 실행되어 예상과 다른 값이 출력된다. 

 

 

👇 await을 넣은 경우 안 넣은 경우 비교

 

async function noAwait() {
 let value = myPromise();
 console.log(value);
}

async function yesAwait() {
 let value = await myPromise();
 console.log(value);
}

noAwait(); // Prints: Promise { <pending> }
yesAwait(); // Prints: Yay, I resolved

 

noAwait은 await 연산자를 쓰지 않아서 value에 프로미스 그 자체가 할당된 걸 알 수 있다.

 


.Then() vs await

 

await의 진가는 서로 의존적인 일련의 비동기적 action들을 처리할 때 나타난다.

 

1. Then을 사용한 경우

 

function nativePromiseVersion() {
    returnsFirstPromise()
    .then((firstValue) => {
        console.log(firstValue);
        return returnsSecondPromise(firstValue);
    })
   .then((secondValue) => {
        console.log(secondValue);
    });
}

 

2. await를 사용한 경우

 

async function asyncAwaitVersion() {
 let firstValue = await returnsFirstPromise();
 console.log(firstValue);
 let secondValue = await returnsSecondPromise(firstValue);
 console.log(secondValue);
}

 

await를 썼을 때 훨씬 코드가 간결해진 걸 알 수 있다.

중요한건 synchronous code에 가까워졌단 사실이다. 이는 디버깅과 유지보수를 쉽게 한다.

그리고 await는 resolved value를 리턴하기 때문에 네이티브 프로미스 문법보다 더 다루기 쉽다.

 


try.. catch..

 

프로미스 함수의 어디에서 에러가 발생했는지 디버깅할 때 쓰는 방법

 

연습으로 작성한 코드

 

const cookBeanSouffle = require('./library.js');

async function hostDinnerParty() {
  try {
    let value = await cookBeanSouffle();
    console.log(`${value} is served!`);
  } catch(error) {
    console.log(error);
    console.log('Ordering a pizza!');
  }
}

hostDinnerParty();

 

cookBeanSouffle()가 제대로 실행되어 resolved value가 저장된다면 try안의 console.log가 실행됨.

 

반대로 실패해서 rejected value가 실행된다면 그 값을 catch의 매개변수 error에 전달하고 다음 괄호 속 코드들을 실행함!

 

한줄요약 : 성공하면 try 실패하면 catch 

 


독립적인 프로미스들 핸들링하기

 

async function waiting() {
 const firstValue = await firstAsyncThing();
 const secondValue = await secondAsyncThing();
 console.log(firstValue, secondValue);
}

async function concurrent() {
 const firstPromise = firstAsyncThing();
 const secondPromise = secondAsyncThing();
console.log(await firstPromise, await secondPromise);
}

 

첫번째 async 함수는 하나가 실행되고 나면 다음 함수를 실행하는 코드이다.

두번째는 async 함수는 비동기적으로 함수들을 처리한 후 각 값을 전달받을 때까지 기다린 후 콘솔에 표시한다.

 


Await Promise.all()

 

await와 promise.all()을 섞어서 사용하는 것도 가능

 

let {cookBeans, steamBroccoli, cookRice, bakeChicken} = require('./library.js')

// Write your code below:

async function serveDinnerAgain(){
  let foodArray = await Promise.all([steamBroccoli(), cookRice(), bakeChicken(), cookBeans()]);

  let broccoli = foodArray[0];
  let rice =  foodArray[1];
  let chicken =  foodArray[2];
  let beans =  foodArray[3];

  console.log(`Dinner is served. We're having ${broccoli}, ${rice}, ${chicken}, and ${beans}.`); 
}

serveDinnerAgain();

 

반응형

관련글 더보기

댓글 영역