inblog logo
|
eunmouse
    javascript

    [자바스크립트] fetch (7)

    단일 스레드인 자바스크립트의 비동기 실행 (async - await fetch)
    Aug 31, 2024
    [자바스크립트] fetch (7)
    Contents
    자바스크립트의 동기 실행 자바스크립트의 비동기 실행 / fetch
     

    자바스크립트의 동기 실행

    아래 코드는 HTML 문서와 함께 JavaScript와 jQuery를 사용하여 동적으로 DOM을 조작하고 서버로부터 데이터를 요청하여 화면에 표시하는 예제이다.
    (요즘은 아래의 방법을 쓰지 않고, fetch 를 사용한다. ^^)
    notion image
    "http://192.168.0.99:8080/test" → 에 5초가 sleep() 걸려있는 상태이다.
    자바스크립트의 동기적 특성은 무조건 종료가 되어야 그림을 그리기 시작한다. `<div>그림</div>`
    코드 실행 순서는 위에서 밑으로 내려가기 때문에, 일단 밑에까지 읽어져야 한다.
    그 전까지는 DOM 을 정리하는 것이다.
    let xhr = download(); 가 5초가 걸리니까 밑의 코드도 안읽어지는 것.
    그래서 ‘그림’ 이라는 텍스트가 5초동안 그려지지 않는 것이다.
    $("#root").append(makeDom()); $("#root").append(makeDom());
    notion image
    이것이 동기적 요청. (단점: 고장난 것 처럼 보인다. UX 사용자 경험이 안좋음)
     
    자바스크립트는 단일 스레드이다. 스레드 하나가 쟤네를 다 실행시키고 끝나는 것.
     
    만약 스레드가 두 개라면 오래걸리는 let xhr = download(); 를 다른 스레드로 넘기고,
    기존 스레드는 실행, 실행해서 그림 그리면 된다. `<div>그림</div>`
    $("#root").append(makeDom()); // 실행 $("#root").append(makeDom()); // 실행
    다른 스레드는 기다리고 있겠지. (5초 sleep 장소에서 대기)
    → 자바의 경우, 멀티스레드 기반이라 이렇게 작동
     
    하지만 자바스크립트는 단일 스레드라서 그렇게 안된다. TT
    비동기로 실행되어야 한다.
     

    자바스크립트의 비동기 실행 / fetch

     
    위의 코드를 비동기로 실행 하게되면,
    notion image
    아래 실행하고 `<div>그림</div>`
    $("#root").append(makeDom()); // 실행 $("#root").append(makeDom()); // 실행
    let xhr = download(); 때리고 자기 볼일 보러 감, 메인으로 하는 자기 할 일 다 끝나고 돌아가면 됨.
    실행은 하는데 안기다리고 내려가는 것. 일의 순서가 없다.
    그림 다 그렸으면 다시 돌아가서 처리 하는 것.
    → 이 때, fetch 를 쓰면 된다.
     

    fetch

    fetch 는 JavaScript에서 URL에 HTTP 요청을 보내는 메서드이다.
    fetch 메서드는 비동기적으로 서버와의 통신을 처리할 수 있게 해주며, URL을 인자로 받아 해당 URL에 HTTP 요청을 보낸다. fetch 는기본적으로 fetch 는 GET 요청을 보내지만, 옵션을 지정하면 POST, PUT, DELETE 등 다른 메서드로 요청을 보낼 수도 있다.
     
    서버는 강사님이 깃헙에 올려주신 서버로 실행하자.
    notion image
    notion image
     

    async - await fetch 사용

     
    fetch는 무겁다. IO 가 일어난다. (입출력은 오래 걸린다. cpu 가 하는게 아니면 오래 걸림)
    오래 걸리는 작업들은 fetch 를 사용하면(5초든.. 몇 초든.. 시간이 걸리는 작업들),
    promise 라는 객체를 준다.(어음을 줌) (F12 누르면 확인 할 수 있다. console.log(response);)
    어음은 실제 값이 아니기 때문에, response 를 실제 값으로 받을 수 있게 await 를 걸어주어야 한다.
     
    await 붙으면 동기가 되기 때문에 5초 있다가 값이 들어온다.
    notion image
    response 는 리얼 값임.
     
    원래는 fetch 를 붙이면 promise 를 준다.
    우리는 await 를 걸어, promise 를 안주고 리얼 값을 준다. 근데 리얼 값은 5초를 기다렸다 줄거야.
    5초 뒤에 json 으로 파싱한다.
    let data = await response.json(); // json 으로 파싱 이것은 문법 -> 자바스크립트로 바뀜
    그림 그리는 시간까지 6초.
    async 를 걸면 비동기 함수가 된다. (async 와 await 는 한 세트)
    notion image
     
    notion image
    그림 그리고
    그림 그리고
    download(); 호출했을 때, → 얘는 비동기 함수구나 하고 fetch 때리면 pending 상태가 됨
    원래 함수는 종료되어야 도망 나갈 수 있음. 끝까지 다 실행되어야 한다.
    근데 비동기 함수는 아님, await fetch 를 체크포인트로 잡고 함수를 그냥 빠져나가버린다. → 비동기함수
    cpu 는 도망나와서 실행한다.
    `<div>그림</div>` 실행
    `<div>그림</div>` 실행
    `<div>그림</div>` 실행
    cpu 할 일 없으니 await 로 다시 돌아간다.
    통신이 끝나면 파싱하고 슥
    <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <div id="root"> </div> <script> function makeDom() { return `<div>그림</div>`; } async function download() { // 비동기로 실행되어야 함 let response = await fetch("http://192.168.0.99:8080/test"); // fetch 는 기본적으로 비동기 함수라 먼저 때림 ㄱ let body = await response.json(); // 기다렸다가 줄거야, await 붙으면 동기적이거든 $("#root").append(`<div>${body}</div>`); } $("#root").append(makeDom()); $("#root").append(makeDom()); download(); $("#root").append(makeDom()); </script> </body> </html>
    시간이 지난 후에 응답데이터 [object Object] 가 뜬다.
    notion image
     
    전체 코드는 비동기적으로 진행되고,
    함수 내부 코드 블락만 동기적으로 실행된다.
    notion image
    (다시 설명)
    await 걸린 await fetch 줄을 21번 메모장에 적어 놓는다.
    원래 stack 이 종료되면 지역변수가 다 날라가지만,
    이 경우에는 stack 이 메모리에 살아있다. 지역변수가 죽지 않는다.
    stack 이 살아있는 상황에서 cpu 가 도망 나온다.
    21번 라인으로 돌아가서 체크해야지~ 하고 cpu 가 이벤트루프로 가서 다시 봐야징~ 하고 간다.
    OS 의 cpu 가 다됐나~ 하고 다른 일 들어오면 그 일 하러 가고~
    cpu 가 풀파워로 체킹하고 있는게 아니라서 다른 일 하고~
    <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <div id="root"> </div> <script> function makeDom() { return `<div>그림</div>`; } async function download() { // 비동기로 실행되어야 함 // 함수 내부 코드 블락은 동기적이다. let response = await fetch("http://192.168.0.99:8080/test"); // fetch 는 기본적으로 비동기 함수라 먼저 때림 ㄱ let data = await response.json(); // 기다렸다가 줄거야, await 붙으면 동기적이거든 // json 으로 파싱 이것은 문법 -> 자바스크립트로 바뀜 $("#root").append(`<div>${data.body}</div>`); } $("#root").append(makeDom()); // 전체코드는 비동기적으로 진행됨 $("#root").append(makeDom()); // 함수 내부 코드블락만 동기적 download(); $("#root").append(makeDom()); </script> </body> </html>
    notion image
     
    Share article
    Contents
    자바스크립트의 동기 실행 자바스크립트의 비동기 실행 / fetch

    eunmouse

    RSS·Powered by Inblog