promise는 생성된 시점에 알려지지 않았을 수도 있는 값을 위한 대리자로 비동기 메서드에서 마치 동기 메서드처럼 값을 return
할 수 있다.
다만 최종 결과를 반환하는 것이 아니고, 미래의 어떤 시점에 결과를 제공하겠다는 '약속'(promise)을 return
한다.
바로 예시 코드를 보자.
function fetchMoviesHandler() {
fetch("https://swapi.dev/api/films")
.then((response) => {
return response.json();
})
.then((data) => {
const transformedMovies = data.results.map((movieData) => {
return {
id: movieData.episode_id,
title: movieData.title,
openingText: movieData.opening_crawl,
releaseDate: movieData.release_date,
};
});
setMovies(transformedMovies);
});
}
위의 코드는 https://swapi.dev/api/films라는 back-end 어플리케이션으로부터 특정 정보를 받아오는 함수이다.
JavaScript 함수 중 fetch()
라는 함수를 통해 Get 방식 요청이 전달되어 Json파일을 받는다.
그 파일을 다시 JavaScript 객체 타입으로 형변환시켜주고 사용하는 개체 속성 이름 값에 맞게 재할당해주는 과정이다.
promise 객체를 다룰 때, 위와 같이 then chain
을 써서 동기적으로 재차 호출할 수 있지만, async
와 await
라는 다른 문법도 사용할 수 있다.
함수 앞에 async
예약어를 추가하고 promise를 반환하는 작업 앞에 await
예약어를 사용한다.
이것은 단순히 코드 변환으로 내부적으로는 then 블록을 사용한 것과 같은 일을 한다.
async function fetchMoviesHandler() {
await fetch("https://swapi.dev/api/films")
...
여기서 조금 더 가독성을 높이려면은 .then 블록을 제거하면 된다.
async function fetchMoviesHandler() {
const response = await fetch("https://swapi.dev/api/films");
const data = await response.json();
const transformedMovies = data.results.map((movieData) => {
return {
id: movieData.episode_id,
title: movieData.title,
openingText: movieData.opening_crawl,
releaseDate: movieData.release_date,
};
});
setMovies(transformedMovies);
}
이런 식으로 코드가 단순해지게 된다. 이것을 비동기화 코드라고 부른다.
겉으로는 단계적으로 실행되는 동기화 코드로 보이지만 내부적으로 아까 사용했던 .then
의 호출로 코드가 반환되고 있다.
async
, await
추가한 이유는 가독성을 높이기 위함이다.