개요
async/await
- Promise를 쉽게 사용하기위해 ES8에 도입
- async는 함수 앞에 위치.
- await는 async 함수 내부에 위치.
- promise를 반환한다
- 비동기 코드를 동기적으로 작성한다
사용 방법
- async 선언된 함수를 만든다.
- try/catch를 통해 예외 처리를 해준다. (선택)
- try 안에 실제로 호출할 비동기 함수(통신 등)을 넣는다.
- 비동기 함수 앞에 await를 넣어준다.
- 만든 함수를 호출한다.
예제
1. async/await를 사용하여 데이터 받아오기
코드
//<script src="https://unpkg.com/axios/dist/axios.min.js"></script> 추가 해주기
const url = "https://jsonplaceholder.typicode.com/todos/";
async function start() {
try {
const result = await axios.get(url);
console.log(result.data);
} catch (error) {
console.log(error);
}
}
start();
출력
실습
1. Playlist를 추천해 주는 웹사이트 만들기
https://console.cloud.google.com/welcome?authuser=2&project=psychic-rhythm-378805 해당 링크에서Youtube data api v3" 검색하여 API키를 발급 받고, axios를 활용하여 유튜브의 API를 가져와 나만의 웹사이트를 만들어 보자
코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<style>
header{
font-size: 30px;
font-weight: bold;
text-align: center;
margin: 20px;
border: 5px solid black;
padding: 20px;
}
.radio-container{
margin: 50px;
display: flex;
justify-content: space-evenly;
}
.radio-btn{
font-weight: bold;
}
.video-container{
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.items{
margin: 10px;
width: 320px;
height: 300px;
}
a {
text-decoration: none;
color: inherit;
}
</style>
</head>
<body>
<header>
집중력 향상을 위한 Playlist 모음
</header>
<main>
<div class="radio-container">
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="rainyDay music"> 비오는 날
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="travel music"> 놀러 가고 싶은 날
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="energy music"> 에너지가 필요한 날
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="game constration music"> 게임에 집중
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="miss home music"> 고향생각이 날때
</div>
</div>
<div class="video-container">
</div>
</main>
<script>
let btn_indexs = document.querySelectorAll(".chk");
btn_indexs.forEach((e) => {
e.addEventListener('change', () => {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
getData(e.id);
})
})
const url = "https://www.googleapis.com/youtube/v3";
const key = "본인의 유튜브 API키 입력";
const container = document.querySelector(".video-container");
async function getData(word) {
try {
const responce = await axios.get(`${url}/search`, {
params: {
key: key,
part: "snippet",
type: "video",
q: word,
maxResults: 10,
},
});
console.log(responce.data.items);
let result = responce.data.items.reduce((acc, cur) => {
acc += getComponents(cur);
return acc;
}, "");
container.insertAdjacentHTML('beforeend', result);
} catch (error) {
console.error(error);
}
}
function getComponents(data) {
return `
<div class="items">
<a href="https://www.youtube.com/watch?v=${data.id.videoId}">
<img src="${data.snippet.thumbnails.medium.url}" alt="">
<div>${data.snippet.title}</div>
</a>
</div>
`
}
</script>
</body>
</html>
결과
radio 버튼의 각 id를 유튜브 검색어로 활용하였고, 각 버튼에 change 이벤트 리스너를 추가해 줘 체크가 변경될 경우 출력한 목록을 모두 지운 뒤 검색어에 알맞은 목록을 다시 노출시킨다.
axios를 통해 API 정보를 받아온 후 각 목록에 대한 배열을 reduce를 통해 순회 한 뒤 HTML 코드를 백틱으로 작성 후 insertAdjacentHTML를 통해 div내로 넘겨주었다.
이후 적당한 style을 적용해주고, 해당 요소를 클릭 시 관련 유튜브 채널로 이동하도록 설정하였다. iframe을 통해 구현하게 된다면 페이지 이동 없이 영상 플레이가 가능하다.
2. 영화 정보를 알려주는 사이트 만들기
https://www.themoviedb.org/ 에 가입하여 API 발급 받고 데이터를 가공하여 영화 정보를 알려주는 사이트를 만들어 보자
API에 대한 자세한 내용은 https://developers.themoviedb.org/3 해당 사이트를 참고하면 된다.
코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<style>
header{
font-size: 30px;
font-weight: bold;
text-align: center;
margin: 20px;
border: 5px solid black;
padding: 20px;
color:black;
background-color: white;
}
.radio-container{
margin: 50px;
display: flex;
justify-content: space-evenly;
}
.radio-btn{
font-weight: bold;
}
.movie-container{
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.items{
margin: 10px;
width: 240px;
height: 450px;
}
a {
text-decoration: none;
color: inherit;
}
body {
background-color: black;
color: white;
}
</style>
</head>
<body>
<header>
영화 정보 특공대 출격!
</header>
<main>
<div class="radio-container">
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=en-US&page=1&sort_by=popularity.desc&with_release_type=2|3&release_date.gte={min_date}&release_date.lte={max_date}"> 현재 상영중
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=en-US&page=1&sort_by=popularity.desc"> 인기 순
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="https://api.themoviedb.org/3/movie/top_rated"> 평점 높은 순
</div>
<div class="radio-btn">
<input class="chk" type="radio" name="music" id="https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=en-US&page=1&sort_by=popularity.desc&with_release_type=2|3&release_date.gte={min_date}&release_date.lte={max_date}"> 최신순
</div>
</div>
<div class="movie-container">
</div>
</main>
<script>
const baseUrl = "https://image.tmdb.org/t/p/w500";
let btn_indexs = document.querySelectorAll(".chk");
btn_indexs.forEach((e) => {
e.addEventListener('change', () => {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
options.url = e.id;
getMovie();
})
})
const container = document.querySelector(".movie-container");
let options = {
method: 'GET',
url: '',
params: {language: 'ko-KR', page: '1'},
headers: {
accept: 'application/json',
Authorization: 'Bearer 본인의 key를 입력'
}
}
async function getMovie() {
axios
.request(options)
.then(function (response) {
console.log(response);
const html = response.data.results.reduce((acc, cur) => {
acc += getComponents(cur);
return acc;
},"");
container.insertAdjacentHTML('beforeend', html);
})
.catch(function (error) {
console.error(error);
});
}
function getComponents(data) {
return `
<div class="items">
<a href="https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=${data.title}">
<img width="240px" height="320px" src="${baseUrl}${data.poster_path}" alt="">
<div>${data.title}</div>
<div>평점 : ${Math.round(data.vote_average, 1)}</div>
<div>추천 수 : ${data.vote_count}</div>
<div>개봉일 : ${data.release_date}</div>
</a>
</div>
`
}
</script>
</body>
</html>
결과
1번과 마찬가지로 axios를 통해 themoviedb 사이트에서 API를 호출하여 포스터 이미지, 영화 제목, 평점, 추천 수, 개봉일 등에 대한 데이터를 파싱해 온 뒤 reduce를 활용하여 각 요소에 대해 HTML 폼을 만든 후 전체 폼을 백틱으로 만들어 insertAdjacentHTML을 통해 body안으로 넣어주었다.
다크 모드를 구현하고 싶어 적당한 style을 입혀 주었고 영화 정보를 클릭하면 네이버 검색으로 이동하게 링크 처리를 해놓았다.
'웹(WEB) > 자바스크립트(JS)' 카테고리의 다른 글
Node.js REST API, HTTP Request (0) | 2024.08.27 |
---|---|
Node.js 기초 및 설치 (0) | 2024.08.27 |
자바스크립트 서버 통신 API 호출 AJAX, Fetch, Axios (0) | 2024.08.07 |
자바스크립트 Promise (0) | 2024.08.07 |
자바스크립트 Callback 콜백 (0) | 2024.08.06 |