20220119 TIL (Callback)

한결·2022년 1월 19일
0

TIL(Today I Learned)

목록 보기
8/14

메서드를 공부하다보면 콜백함수라는 개념을 보게된다.
콜백은 함수의 인자에 함수가 들어가 실행시켰을 때, 인자로 들어간 함수도 실행이 된다.
자바스크립트는 비동기적코드를 먼저 실행시킨다.

callback 지옥

<!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를 적극 활용해서 작성하도록 하자 ~~

0개의 댓글