fetch
- XMLHttpRequest(=callback방식으로 전달하는 객체)의 callback 방식을 개선해 Promise를 통한 then절에서 응답결과를 처리할 수 있다.
btn1.onclick = () => {
console.log(
fetch(USER_URL)
.then((response) => {
console.log(response);
return response.json(); // message body 적힌 부분을 추출하는 promise가 한 단계필요하다.
})
.then((data) => console.log(data))
);
};
USER_URL 은 {"id":"shqkel","company":"KH정보교육원","classroom":"M","cnt":1} 라는 값을 가진 데이터이다.
닫혀있을때는 pending이라는 값을 출력하지만 ( ??? ) 열게되면 resolve에서 값을 받아서 fulfilled 를 출력하게 된다.
USER_URL 에 들어있는 값이 제대로 출력되는 것을 확인할 수 있다.
fetch는 return response.json(); 이라는 message body가 적힌 부분을 추출하는 코드가 따로 필요하다.
아바타 렌더하기
GITHUB_URL은 github의 개인 정보를 가지고 있다.
- 유저정보 가져오기
- 1.의 유저아이디로 github 사용자정보 가져오기
- 2번의 사용자정보중 avatar_url로 img태그 생성하기
- 3번의 이미지 로딩이 완료되면 메세지 출력하기
를 실행해보려고 한다.
</script>
<div class="img-wrapper"></div>
<style>
.img-wrapper img {
margin: 10px;
width: 300px;
border-radius: 50%;
box-shadow: 5px 5px 10px 5px lightgray;
}
</style>
btn2.onclick = () => {
fetch(USER_URL)
.then((response) => response.json())
.then((user) => {
console.log(user);
const {id} = user;
return fetch(`${GITHUB_URL}${id}`); // 명시적으로 promise 리턴
})
.then((response) => response.json())
.then((githubUser) => {
console.log(githubUser);
const {avatar_url} = githubUser;
return loadUserImg(avatar_url);
})
.then(() => console.log("이미지 로딩 완료!"));
};
const loadUserImg = (src) => {
return new Promise((resolve) => {
const img = document.createElement("img");
img.src = src;
img.onload = () => resolve();
document.querySelector(".img-wrapper").append(img);
});
};
btn2. onclick 구조 설명 )
USER_URL을 fetch로 받으면, then으로 response를 보낸다. (json으로 처리한 body에 적힌 값.)
then으로 user를 출력한다.
user의 값중 사용할 id값을 리턴한다 (명시적으로 promise리턴)
이 리턴한 값을 가지고 다시 then으로 response를 보내고, githubUser를 요청한다.
const {avatar_url} 으로 아바타url을 꺼낸다.
이 꺼낸 url의 이미지를 받아서 querySellector로 img-wrapper에 추가하도록 만든 함수인 loadUserImg에 avatar_url값을 변수로 준다.
이렇게 이미지 로딩이 완료되었다!
axios
axios cdn 검색 - <scriptsrc="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> 입력
<script>
btn3.onclick = () => {
axios(USER_URL)
.then((response) => {
const {id} = response.data;
alert(`사용자의 아이디는 ${id}입니다.`);
});
};
</script>
위의 fetch보다 더 빠르게 확인 가능.
btn4.onclick = () => {
axios("https://dog.ceo/api/breeds/image/random")
.then(({data}) => loadDogImage(data))
.then((img) => {
img.remove();
console.log('dog 이미지 제거완료!');
});
};
const loadDogImage = (data) => {
return new Promise((resolve) => {
const {message, status} = data;
if(status === 'success'){
const img = document.createElement("img");
img.src = message;
img.onload = () => {
console.log('dog 이미지 로드완료!');
setTimeout(() => {
resolve(img);
}, 3000);
};
const wrapper = document.querySelector(".dogs");
wrapper.innerHTML = ""; // 초기화
wrapper.append(img);
}
});
}
이렇게 강아지가 로드되고, 3초뒤에 제거된다.
강아지 사진은 랜덤으로 나오고, dog ceo 라는 사이트에서 dog api 를 가져온 것이다.
async
ES2017에 추가된 일반함수의 Promise화를 지원하는 문법
await
async함수 안에서만 사용이 가능
promise의 동기적 처리를 지원
btn1.addEventListener('click', () => {
zoo()
.then((value) => console.log(value));
});
const zoo = async () => 10;
async로 불러온 zoo가 콘솔창에 Promise문법인 then으로 전달된 것을 확인할 수 있다.
btn2.addEventListener('click', async () => {
// 프라미스 사용
// xoo()
// .then((value) => console.log(value));
const value = await xoo();
console.log(value);
});
const xoo = () => new Promise((resolve) => {
setTimeout(() => resolve(100), 3000);
});
(async () => {
const value = await xoo();
console.log(value);
})();
창이켜지고 3초뒤, 100이 resolve를 통해서 출력되는 것을 확인할 수 있다.
xoo는 Promise문법, async로 전달한 await xoo(=value)를 통해 value값(=100)이 전달된다
btn3.addEventListener('click', async () => {
// loadScript('js/1.js')
// .then(() => loadScript(bar()))
// .then(() => loadScript(car()))
// .then(() => dar());
await loadScript('js/1.js'); // resolve되기전까지 기다린다.(동기적)
let path = bar();
await loadScript(path);
path = car();
await loadScript(path);
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);
});
주석 부분은 promise문법.
await fetch
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);
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);
});
Promise때와 같은 사진 불러오기 성공
Random Dog
btn5.onclick = async () => {
const {data} = await axios("https://dog.ceo/api/breeds/image/random");
const img = await loadDogImage(data);
img.remove();
console.log('dog 이미지 제거완료!');
};
const loadDogImage = (data) => {
return new Promise((resolve) => {
const {message, status} = data;
if(status === 'success'){
const img = document.createElement("img");
img.src = message;
img.onload = () => {
console.log('dog 이미지 로드완료!');
setTimeout(() => {
resolve(img);
}, 3000);
};
const wrapper = document.querySelector(".dogs");
wrapper.innerHTML = ""; // 초기화
wrapper.append(img);
}
});
}