Medium - How to use Async / Await in JavaScript

원문 - Akash Bhandwalkar

Trend 파악을 Medium 기고문 요약 포스팅 - 자바스크립트에서 Async/Await를 사용하는 법; Async / Await는 자바스크립트에서 비동기 호출을 처리하기 위한 대체적인 방법입니다.

Async / Await

What is async?

async 키워드는 모든 함수 앞에 붙일 수 있습니다. 한번 함수 앞에 위치하면 함수가 promise를 리턴하도록 보장합니다. 비동기 함수를 사용하기 위해서는 아래의 코드와 같이 전통적인 promise를 사용한 함수를 해결하거나 콜백 접근을 해야합니다.

asnyc function getCompany() {
  return 'clairvoyant';
}

getCompany().then( (res) => {
  console.log('res-->', res);
  })

Node.js 터미널이나 개발자 도구에서 위의 프로그램을 실행시키면 getCompany 함수에서 하나의 문자열만 리턴해도 여러분은 프로미스를 해결할 수 있습니다.

What is await?

await는 자바스크립트에서 비동기 블록 선언에 사용할 수 있는 또 다른 키워드 입니다. await는 asnyc 없이는 의미도 없고 존재할 수도 없습니다. 만약 비동기 호출앞에 await를 사용하면 특정 프로미스가 세팅될 때 까지 기다리게 되고 그 다음에 비동기 블록의 코드가 실행될 것입니다. 아래의 예제를 보시면 await가 어떻게 async와 사용될 수 있는지 잘 이해하시게 될겁니다.

function serverRequest() {
  var promise = new Promise( (resolve, reject) => {
    setTimeout(() => resolve('clairvoyant'), 3000)
    })
    return promise;
}

async function getCompany() {
  let companyPromise = serverRequest();
  let companyName = await companyPromise;
  console.log('companyName', companyName);
}

getCompany();

console.log('Is async / await blocking JavaScript');
//Is async / await blocking JavaScript
//companyName clairvoyant

위의 프로그램을 실행시켜보면 await가 오직 async 블록만을 기다린다는 것을 알 수 있습니다. await는 자바스크립트가 다른 연산들을 실행하는 것을 막지 않습니다.

How can we handle errors in async / await block?

프로미스가 변수안에 catch/error 블록이 있는 것과 달리 await는 에러를 위한 특별한 처리가 없습니다. 아래와 같이 await구문 위에 try-catch 구문을 사용해야 합니다.

function serverRequest() {
  var promise = new Promise( (resolve, reject) => {
      setTimeout(() => reject('error in getting'), 3000)
    })
    return promise;
}
async function getCompany() {
  let companyPromise = serverRequest();
  try{
    let companyName = await companyPromise;
    console.log('companyName', companyName);
    //handle success
  } catch(error) {
    console.log('error', error);
    //handle error
  }
}
getCompany();

Chaining of Multiple Asynchronous calls using Async/Await

async/await가 보기엔 간단해 보이지만 프로미스 대신에 사용할 정도로 우리를 확신시키지는 못합니다. 하지만 프로미스는 복잡한 상황에서는 몇 가지 값을 더 추가해야만 합니다. 더욱 복잡한 비동기 처리 상황은 서로 의존관계에 있는 다수의 호출을 할 때입니다.

Problem Statement

여러분은 학급 내에 가장 키가 큰 학생의 자세한 정보를 표시해야 합니다. 하나의 엔드포인트는 가장 키가 큰 학생의 ID가 주어지고 또 다른 엔드포인트는 주어진 ID를 가지고 학생 정보를 가져오는 것입니다. async/await를 이용해서 어떻게 이 문제를 풀 수 있을까요?

Solution 1: using async / await

function getTallestPerson() {
    var promise = new Promise( (resolve, reject) => {
        setTimeout(() => resolve(123),1000);
      });
      return promise;
}
function getUserDetails(studentId) {
  var promise = new Promise( (resolve, reject) => {
    setTimeout(() => resolve({
                              id: studentId,
                              name: 'John',
                              company: 'clairvoyant'
                              }), 1000);
    });
    return promise;
}

const getUser = async () => {
	const studentId = await getTallestPerson()
	const user = await getUserDetails(studentId);
	console.log(user);
}
getUser()

Solution 2: using promise chain

function getTallestPerson() {
    var promise = new Promise( (resolve, reject) => {
        setTimeout(() => resolve(123),1000);
      });
      return promise;
}
function getUserDetails(studentId) {
  var promise = new Promise( (resolve, reject) => {
    setTimeout(() => resolve({
                              id: studentId,
                              name: 'John',
                              company: 'clairvoyant'
                              }), 1000);
    });
    return promise;
}

const getUser = () => {
  getTallestPerson().then( studentId => {
      return getUserDetails(studentId);
    })
    .then( userDetails => {
      console.log('userDetails', userDetails);
    })
}
getUser()

이제 양쪽 해답이 있으니 코드를 비교해 봅시다. 결론을 내기에는 너무 subset이 작지만 우리가 하나당 5개 이상의 서버의 요구사항을 처리해야 한다고 생각해보세요. 해당 경우에 async / await는 다음과 같은 장점이 있습니다.

  1. 코드 가독성
  2. 명확하고 간결한 코드
  3. 디버깅

Summary

  • async / await와 프로미스 체이닝의 장단점 비교
  • promise를 기반으로 하는 async/await 가독성이 좋고 무엇보다 디버깅 시에 어디서 오류가 발생했는지 추적할 수 있다는 큰 장점이 있다.
  • 일부 function 키워드를 화살표 함수 형태로 변경함

© 2019. All rights reserved.

Powered by Hydejack v8.1.1