본문 바로가기

JS

자바스크립트 딥다이브 - 42 비동기 프로그래밍, 43 Ajax

42 비동기 프로그래밍

콜스택 = "실행 컨텍스트"

함수가 '호출'되면 스택에 푸쉬되어 순차적으로 실행된다. 

자바스크립트 엔진은 단! 하나의 콜스택을 사용하기 때문에, 종료되기 전까지 다른 어떤 테스크도 실행되지 않는다. 

 

힙은 객체가 저장되는 메모리 공간이다. 

콜스택의 요소인 '실행 컨텍스트'는 힙에 저장된 객체를 참조한다. 

 

테스크큐

setTimeout 과 같은 비동기 콜백 함수들이 일시적으로 보관되는 장소

 

 

 

-> 자바스크립트의 동시성을 지원하는 것이 '이벤트 루프'

 

 

 

 

 


 

 

 

43 Ajax

최신 브라우저는 fetch 를 제공하지만 xhr로 비동기 통신을 지원해야 하는 경우도 있다. (이전 브라우저 등등...)

많은 경우의 수로  fetch를 사용하는 것이 더 좋긴 하다. 

 


//xhr 만들기
let xhr = new XMLHttpRequest();

//open으로 초기화 하기
xhr.open('GET', END_POINT);

//HTTP요청 header의 값을 설정하기
xhr.setRequestHeader('name', 'chaeyoung'); //헤더이름, 헤더값

//send하기
xhr.send();

1. xhr 객체 생성

2. open 으로 통신메서드, url 초기화

3. HTTP 요청 header 값 초기화

4. send()

 

 

 

xhr 을 이용한 콜백 프로그램

/* -------------------------------------------------------------------------- */
/*                                 xhr Callback                                */
/* -------------------------------------------------------------------------- */


function xhr({ //객체를 인수로 받는 xhr 선언과 초기화
    method = "GET",
    url = "",
    onSuccess = null,
    onFail = null,
    body = null,
    headers = {
        "Content-Type" : "application/json",
        "Access-COntrol-Allow-Origin" : "*",
    },
}){
    const xhr = new XMLHttpRequest();

    xhr.open(method, url);

    Object.entries(headers).forEach(()=>{ //Object.entries는 [키, 값] 배열을 쌍으로 반환한다.
        xhr.setRequestHeader(key,value); //반환되는 배열의 key와 value 값으로 HTTP 초기화
    });

    xhr.addEventListener("readystatechange", () => { //readystatechange 라는 페이지 로딩 이벤트 정의, 핸들러 함수를 바로 생성
        const {readyState, status, response} = xhr; //객체 구조 분해 할당

        if(readyState === 4 ){ //데이터를 전부 받은 상태인 readyState = 4
            if(status >= 200 && status < 400){
                onSuccess(JSON.parse(response)) // 응답을 parse해서  onSuccess 를 실행
            } else {
                onFail({messafe : '에러가 발생했습니다.'}) //오류가 발생했다면 이 것을 반환
            }

        }
    });

    xhr.send(JSON.stringify(body));
}



 

 

//xhr의 메서드 정의 ? 


xhr.get = (url, onSuccess, onFail) => {
  xhr({
    url,
    onSuccess,
    onFail,
  });
};

xhr.post = (url, body, onSuccess, onFail) => {
  xhr({
    method: "POST",
    url,
    body,
    onSuccess,
    onFail,
  });
};

xhr.put = (url, body, onSuccess, onFail) => {
  xhr({
    method: "PUT",
    url,
    body,
    onSuccess,
    onFail,
  });
};

xhr.delete = (url, onSuccess, onFail) => {
  xhr({
    method: "DELETE",
    url,
    onSuccess,
    onFail,
  });
};

 

 

 

 

 

fetch 

const tiger = async (options) => {
    const {url,...restOptions} = { //url만 뽑아오도록 구조분해 할당
        ...defaultOptions,
        ...options,
        headers:{
          ...defaultOptions.headers,
          ...options.headers
        }
      };

    const response = await fetch(url, restOptions);

    if(response.ok) { //응답 상태가 200과 299 사이에 있는 경우(즉 성공 시) true
        response.data = await response.json(); //데이터를 얻어올 때에는 json()으로 얻어온다.
    }
    return response
}

tiger.get = (url, options) => { //기본 메서드가 get이므로 전달하지 않는다.
    return tiger({ //tiger 함수에 객체를 전달하면서 return (즉 promise 리턴?)
        url,
        ...options
    })
}

기본 매개변수와 전달된 객체가 합쳐져서 (mixin) 된다. 

 

보다 편하게 사용하기 위해서  + 가독성 을 위해서 메서드를 따로 빼줬다. 메서드를 전달하지 않고 바로바로 사용하도록 !

>> 함수 안에서는 사용할 수 없고, 바로바로 tiger함수에다가 메서드를 삽입하려고 하는 것이다. 

js의 함수는 원래는 '객체 object' 따라서 tiger에게 get이라는 메서드를 추가해준 형태이다. 

 

body는 stringify 하여 전달 필

const response = await tiger.get(END_POINT); //사용 시

async / await을 이용해서 구현!