카테고리 없음

[Django] Ajax(서버 통신)

황성안 2021. 5. 4. 14:00
728x90

AJAX

서버와 통신할때 사용한다

Asynchronous Javacript And XML( 비동기식 js와 xml )

핵심 : XMLHttpRequest(XHR)

서버간 통신 보기

ex) 구글 맵스에서 f12 개발자도구 > network

가고싶은곳으로 가보면 XHR 스캔시에 구글서버 요청을 보낸다.

blocking -example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>게시판</h1>
    <ul id="article-list">
        <li>게시글 1</li>
        <li>게시글 2</li>
    </ul>
    <button id="long-task"> 굉장히 오래 걸리는 어떤 일</button>
    <button id="add-article">게시글 추가</button>

    <script>
        const longTask = document.querySelector('#long-task')
        longTask.addEventListener('click', function() {
            let sum = 0
            for (let i=0; i<1000000000; i++) {
                sum += 1
            }
            alert('끝!')
        })

        const addArticle = document.querySelector('#add-article')
        addArticle.addEventListener('click', function() {
            const articleList = document.querySelector('#article-list')
            const newLi = document.createElement('li')
            newLi.innerText = '새로운 게시글'
            articleList.append(newLi)
        })
    </script>
</body>
</html>

여기서 블로킹이되어 브라우져가 멈춰버린다.

반대로 non-blocking 을살펴보자

hello > bye > done 순으로 뜬다.

개발자 도구 콘솔에서봅시다.

코드 실행 순서는 hello > done > bye 가 맞다

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        console.log('Hello!')

        setTimeout(function() {
            console.log('done')
        }, 5000)

        console.log('bye')
    </script>
</body>
</html>

왜?

0초로 바꿔도 hello > bye > done 이다. 왜????

wep api 보내서 그렇다.

non-blocking선상이며 JS에서 비동기적으로 처리하기떄문이다

대표적으로 setTimeout, Network 요청, File I/O

1

call Stack: console hello!
 web api:
Output : hello!

2

call Stack: settime ... 5000)
 web api:
Output : 

3 웹 api 에서 계속 도릴거임

call Stack: 
 web api:settime ... 5000)
Output : 

4

call Stack: console bye
 web api: 
Output : 

5

call Stack: 
 web api: 
Output : bye

6 끝난 web api 도 Task Queue 로이동해주고 callstack으로 찍힌다

call Stack: done
 web api: 
Output : done

참고 : https://www.youtube.com/watch?v=8aGhZQkoFbQ

애니메이션으로보기 : http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

비동기적으로 작동하는 경우를 보자

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // JS 비동기 요약
        // 1. JS에서 어떤 코드들은 메인 코드의 흐름과 별개로
        // "비동기적으로" 진행된다. (ex. setTimeout, network 요청)
        // 2. 이 때, 해당 코드의 다음 코드들은 기다려주지 않고
        //    쭉 진행된다. (non-blocking)
        // 3. 비동기적으로 처리된 코드는 
        //    "언제 처리될지는 모르지만 완료되는 시점에" 다음 일을 해야한다.
        //    - 콜백 방식
        //    - 프로미스 방식
        //  network 요청 옛날 방식
        const xhr = new XMLHttpRequest()
        // 오픈 처음에 메소드 적어줘야함
        xhr.open('GET', 'https://dog.ceo/api/breeds/image/random')
        xhr.send() // -> 이친구가 ㅣㅂ동기적으로 작동한다

        const res = xhr.response 
        console.log(res)


    </script>
</body>
</html>

xhr.send()의 값이 const res = xhr.response에 담겨있다고 생각하면 안된다.

이 완료시점을 알수있게 xhr.onload = function() {} 을 사용해준다.

잘안쓰는 방식

    <script>
        xhr.open('GET', 'https://dog.ceo/api/breeds/image/random')
        xhr.send()
        xhr.onload = function() {
            console.log('응답 완료!')
            console.log(xhr.response)
        }


        const res = xhr.response
        console.log(res)


    </script>

잘 사용하는 방식( 신세대 )

페치방식

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // JS 비동기 요약
        // 1. JS에서 어떤 코드들은 메인 코드의 흐름과 별개로
        // "비동기적으로" 진행된다. (ex. setTimeout, network 요청)
        // 2. 이 때, 해당 코드의 다음 코드들은 기다려주지 않고
        //    쭉 진행된다. (non-blocking)
        // 3. 비동기적으로 처리된 코드는 
        //    "언제 처리될지는 모르지만 완료되는 시점에" 다음 일을 해야한다.
        //    - 콜백 방식
        //    - 프로미스 방식
        //  network 요청 옛날 방식
        // const xhr = new XMLHttpRequest()
        // // 오픈 처음에 메소드 적어줘야함
        // xhr.open('GET', 'https://dog.ceo/api/breeds/image/random')
        // xhr.send()
        // xhr.onload = function() {
        //     console.log('응답 완료!')
        //     console.log(xhr.response)
        // }


        // const res = xhr.response
        // console.log(res)

        // 2세대 방식 (fetch)
        fetch('https://dog.ceo/api/breeds/image/random')
        .then((res) => {
            // console.log(res)
            //json 으로 바꾸고싶다면
            return res.json() // 이것 조차 비동기..
        })
        // 이제 진짜 내가 할일
        .then((res) => {
            console.log(res.message)
        })



    </script>
</body>
</html>

옜날 방식

        // 옜날방식이고 요즘은 .then .then 을 통해서 함
        setTimeout(function() {
            setTimeout(function() {
                setTimeout(function() {
                    setTimeout(function() {

                    }, 5000)
                }, 5000)
            }, 5000)
        }, 5000)
728x90