[Javascript] Async Method

Song-YunMin·2021년 2월 18일
3

JavaScript

목록 보기
17/22

Promise로 HTTP 통신을 하기 위해서는?

HTTP 통신을 하기 위해 Promise 가 어떻게 사용되는지 살펴 보겠습니다. 아래 예제에 사용된 axios 는 Javascript를 통해 직접 요청을 보내기 위해 널리 사용되는 라이브러리 입니다. GET 메서드로 요청을 보내기 위해 axios.get() 함수를 사용할 수 있는데, 이 때 Promise 객체가 반환됩니다.

const axios = require('axios');
const API_URL = 'https://api.github.com';

axios.get(`${API_URL}/repos/facebookincubator/create-react-app/issues?per_page=10`)
	.then(res => {
		console.log('최근 10개의 이슈');
		res.data
			.map(issue => issue.title)
			.forEach(title => console.log(title));
		console.log('출력이 끝났습니다.');
	});

axios.get() 을 호출해서 반환된 Promise 객체에 담긴 결과값은 Response 객체로, HTTP 응답에 대한 내용을 담고 있습니다.

Promise 의 진가는, 복잡한 비동기 데이터 흐름을 다룰 때 발휘됩니다.

아래의 두 특징을 활용하면, 콜백만 사용했을 때보다 코드를 훨씬 더 깔끔하게 작성할 수 있습니다.

  • then 메서드는 Promise 객체를 반환하므로, 콜백을 중첩하지 않고도 비동기 작업을 연이어 할 수 있습니다.
  • 비동기 작업이라는 동작 자체를 값으로 다룰 수 있게 됩니다. 즉, 이제까지 값을 다루면서 해왔던 모든 작업을 Promise 객체에 대해서도 할 수 있습니다.

비동기 함수 (Async Function)

Promise 를 사용하는 비동기 프로그래밍 방식은 여러가지 장점을 갖지만, 여전히 콜백은 사용한다는 점 때문에 '불편하다', '가독성이 좋지 않다' 는 비판을 받았습니다.

ES2017에서 도입된 비동기 함수(async Function)을 사용하면, 동기식 코드와 거의 같은 구조를 갖는 비동기식 코드를 짤 수 있습니다.

함수 앞에 async 키워드를 붙이면 그 함수는 비동기 함수가 됩니다.

// 비동기 함수
async function func1() {
  // ...
}

// 비동기 화살표 함수
const func2 = async () => {
  // ...
}

// 비동기 메소드
class MyClass {
  async myMethod() {
    // ...
  }
}

비동기 함수는 항상 Promise 객체를 반환하는 특징을 가지고 있습니다. 이 Promise 의 결과 값은 비동기 함수 내에서 무엇을 반환하느냐에 따라서 결정되며, then 메서드와 똑같은 방식으로 동작합니다.

async function func1() {
  return 1;
}

async function func2() {
  return Promise.resolve(2);
}

func1().then(console.log); // 1
func2().then(console.log); // 2

또 하나의 중요한 특징은 비동기 함수 내에서 await 키워드를 쓸 수 있습니다. awaitPromisethen 메서드와 유사한 기능을 하는데, await 키워드 뒤에 오는 Promise 가 결과값을 가질 때 까지 비동기 함수의 실행을 중단 시킵니다.

'중단'에 의미는 비동기식이며, 브라우저는 Promise 가 완료될 때까지 다른 작업을 처리할 수 있습니다.

await 는 연산자이기도 하며, await 연산의 결과값은 뒤에 오는 Promise 객체의 결과값이 됩니다.

then 을 이용하여 작성하는것 보다 아래처럼 작성하는게 더 동기식 코드를 짜듯이 비동기식 코드를 짤 수 있습니다.

// Promise 객체를 반환하는 함수.
function delay(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`${ms} 밀리초가 지났습니다.`);
      resolve()
    }, ms);
  });
}

async function main() {
  await delay(1000);
  await delay(2000);
  const result = await Promise.resolve('끝');
  console.log(result);
}

main();

await 키워드는 forif와 같은 제어 구문 안에서도 쓰일 수 있기 때문에, then 메소드를 사용할 때보다 복잡한 비동기 데이터 흐름을 아주 쉽게 표현할 수 있다는 장점이 있습니다. 다만, 비동기 함수 역시 Promise를 사용하기 때문에, 비동기 함수를 잘 쓰기 위해서는 여전히 Promise에 대해 잘 알고 있어야 합니다.

Reference

비동기 프로그래밍

profile
고독한 서버 개발 3년차

0개의 댓글