본문 바로가기
JavaScript/JavaScript

Javascript) async & await (await fetch, 랜덤 강아지/고양이 사진 추출)

by 박채니 2022. 6. 10.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


async

- ES2017에 추가된 일반 함수의 프라미스화를 지원하는 문법

 

HTML 코드

<button id="btn1">async</button>

 

Javascript 코드

 

Promise화 하는 방법

① new Promise 객체 반환

btn1.addEventListener('click', () => {
    zoo()
    .then((value) => console.log(value))
});

const zoo = () => new Promise((resolve) => resolve(10));

Promise 객체를 반환하고 then에서 콜백함수를 실행해주어 10을 출력해줍니다.

 

② Promise.resolve() 이용

btn1.addEventListener('click', () => {
    zoo()
    .then((value) => console.log(value))
});

const zoo = () => Promise.resolve(10);

 

③ async 이용

btn1.addEventListener('click', () => {
    zoo()
    .then((value) => console.log(value))
});

const zoo = async () => 10;

일반함수를 프라미스화해주는 async을 이용하여 10을 출력해줍니다.

 


await

- async 함수 안에서만 사용 가능

- promise의 동기적 처리를 지원

 

HTML 코드

<button id="btn2">await</button>

 

Javascript 코드

btn2.addEventListener('click', async () => {
    const value = await xoo();
    console.log(value)
});

const xoo = () => new Promise((resolve) => {
    setTimeout(() => {
        resolve(100);
    }, 3000);
});

비동기 처리를 기다렸다가 resolve에 전달된 value값을 반환 받습니다. (result를 반환하길 기다렸다가 반환 후 실행)

마치 동기적인 처리를 하는 것 같습니다.

 

실습 - script 로딩

btn3.addEventListener('click', async () => {
    await loadScript('../js/1.js'); // resolve 될때까지 기다림
    await loadScript(bar());
    await loadScript(car());
    dar();
});

const loadScript = (path) => new Promise((resolve) => {
    const script = document.createElement("script");
    script.src = path;
    script.onload = () => {
        console.log(`${path} 로딩완료!`);
        resolve();
    };
    document.head.append(script);
});

async & await을 사용하여 resolve처리가 될 때까지 기다리므로 마치 동기적처리가 되는 효과가 나타납니다.

 


await fetch

 

HTML 코드

<button id="btn4">await fetch</button>

 

Javascript 코드

<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.0.0-alpha.1/axios.min.js" integrity="sha512-xIPqqrfvUAc/Cspuj7Bq0UtHNo/5qkdyngx6Vwt+tmbvTLDszzXM0G6c91LXmGrRx8KEPulT+AfOOez+TeVylg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<script>
const USER_URL = "https://asia-northeast3-focal-elf-326215.cloudfunctions.net/user";    // google cloud function
const GITHUB_URL = "https://api.github.com/users/";

btn4.addEventListener('click', async () => {
    const resp = await axios(USER_URL);
    console.log(resp)
});
</script>

async & await을 이용하여 데이터를 가져왔습니다.

 

btn4.addEventListener('click', async () => {
    const resp = await axios(USER_URL);
    console.log(resp)

    const {data : {id}} = resp;

    const {data : {avatar_url}} = await axios(GITHUB_URL + id);
    console.log(avatar_url);

    const img = await loadImg(avatar_url);
    setTimeout(() => {img.remove();}, 3000);
});

const loadImg = (url) => new Promise((resolve) => {
    const img = document.createElement("img");
    img.src = url;
    img.onload = () => resolve(img);
    document.body.append(img);
});

이미지가 잘 로드 되고, 로드 되는 것을 기다렸다가 3초 뒤에 이미지가 제거 되는 것을 확인할 수 있습니다.

 


랜덤 강아지 사진 추출

HTML 코드

<button id="btn5">Random Dog</button>
<div class="dogs pet-wrapper"></div>

 

Javascript 코드

btn5.addEventListener('click', async () => {
    const {data} = await axios("https://dog.ceo/api/breeds/image/random");
    const img = await loadDogImage(data);
    img.remove();
});

const loadDogImage = (data) => new Promise((resolve) => {
    const {message, status} = data;
    if(status === 'success') {
        const wrapper = document.querySelector(".dogs");
        const img = document.createElement("img");
        img.src = message;
        img.onload = () => {
            setTimeout(() => {
                resolve(img);
            }, 3000);       
        }
        wrapper.innerHTML = '';
        wrapper.append(img);
    }
});

async & await을 이용하여 보다 간편하게 데이터를 불러오고, 이미지 파일을 제거할 수 있습니다.

이미지가 onload 된 후 3초 뒤에 resolve(img)가 실행되는데 이 실행을 await으로 기다리고, result값을 return (img)해주어 해당 리턴 값을 가지고 이미지를 제거해주었습니다.

 


랜덤 고양이 사진 추출

HTML 코드

<button id="btn6">Random Cat</button>
<div class="cats pet-wrapper"></div>

CSS 코드

<style>
.pet-wrapper img {
    width: 300px;
    transition-duration: 1s;
}	
</style>

 

Javascript 코드

btn6.addEventListener('click', async () => {
    axios.defaults.headers.common['x-api-key'] = "키값";

    const {data : [{url}]} = await axios('https://api.thecatapi.com/v1/images/search', { params: { limit:1, size:"full" } });
    const img = await loadCatImg(url);
    await new Promise((resolve) => {
        img.ontransitionend = () => {
            console.log('transtion이 종료되었습니다.');
            resolve();
        };
        setTimeout(() => {
            img.style.opacity = 0;
        }, 3000);
    })
    img.remove();
});

const loadCatImg = (url) => new Promise((resolve) => {
    const wrapper = document.querySelector(".cats");
    const img = document.createElement("img");
    img.src = url;
    img.onload = () => resolve(img);
    wrapper.innerHTML = '';
    wrapper.append(img);
});

비동기처리 함수들을 async & await을 이용해 동기적으로 처리하였습니다.