메서드를 공부하다보면 콜백함수라는 개념을 보게된다.
콜백은 함수의 인자에 함수가 들어가 실행시켰을 때, 인자로 들어간 함수도 실행이 된다.
자바스크립트는 비동기적코드를 먼저 실행시킨다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>콜백과 칭구들</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function myCallback(){
const ccc = new XMLHttpRequest()
ccc.open("get","http://numbersapi.com/random?min=1&max=200")
ccc.send()
ccc.addEventListener("load",(res) => {
console.log('데이터가 로드되면 실행시켜줘')
console.log(res)
const num = res.target.response.split(" ")[0]
const ddd = new XMLHttpRequest()
ddd.open("get", `http://koreanjson.com/posts/${num}`)
ddd.send()
ddd.addEventListener("load",(res) => {
console.log("두번째는 이거 실행")
console.log(res)
console.log(JSON.parse(res.target.response))
const userId = JSON.parse(res.target.response).UserId
const eee= new XMLHttpRequest()
eee.open("get", `http://koreanjson.com/posts?userId=${userId}`)
eee.send()
eee.addEventListener("load",(res)=>{
console.log('마지막으로 이거 실행')
console.log(res.target.response)
})//콜백지옥 !!!
})
})
}
해당 코드는 옛날 XML 시절에 작성하던 방법이라고 한다.
myCallback()
함수를 실행시키면, 그 안에 있는 ccc
,ddd
,eee
가 연쇄적으로 실행된다. 이런 무한 루프를 콜백 지옥이라고 한다.
function myPromise(){
console.log('1번실행')
const result = axios.get('http://numbersapi.com/random?min=1&max=200')
.then((res)=>{
console.log('2번실행')
const num = res.data.split(' ')[0]
return axios.get(`http://koreanjson.com/posts/${num}`)
})
.then((res)=>{
console.log('3번실행')
const userId=res.data.UserId
return axios.get(`http://koreanjson.com/posts?userId=${userId}`) //여기에서 .then 써도되고
}).then((res)=>{//여기에서 .then 해도됨
console.log('4번실행')
console.log(res.data)
}).catch((error)=>{
console.log(error)
})///프로미스 체인 !!!!
console.log('5번실행')
}
axios을 사용해 바꿔본다면 위와 같다. 이는 프로미스 체인이라고 부른다. promise
의 인자로 넘겨주는 콜백함수는 resolve
또는 reject
함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행되기 전까지 then
이나 catch
로 넘어가지 않는다.
.then
을 사용해 return 값에 이어 함수를 실행시킨다.
단, 콘솔로 확인해본다면, 순서대로 1->2->3->4->5를 실행시키는것이 아니라 1->5->2->3->4 순으로 실행이 된다.
async function myAsyncAwait(){
const res1 = await axios.get('http://numbersapi.com/random?min=1&max=200')
const num = res1.data.split('')[0]
const res2 = await axios.get(`http://koreanjson.com/posts/${num}`)
const userId = res2.data.UserId
const res3 = await axios.get(`http://koreanjson.com/posts?userId=${userId}`)
console.log(res3.data)
}
</script>
</head>
<body>
<button onclick="myCallback()">Callback 연습하기</button>
<button onclick="myPromise()">Promise 연습하기</button>
<button onclick="myAsyncAwait()">AsyncAwait 연습하기</button>
</body>
</html>
이번엔 async/await
와 axios를 이용해 get요청을 보내 데이터를 받았다.
비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고, 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await를 표기하는 것만으로 뒤의 내용을 Promise
로 자동 전환하고 해당 내용이 resolve된 이후에야 다음으로 진행이 된다.
async와 await를 적극 활용해서 작성하도록 하자 ~~