[day-29] Ajax

Joohyung Park·2024년 2월 7일
0

[모두연] 오름캠프

목록 보기
44/95

Ajax 탄생 배경

자바스크립트 기술을 이용해 비동기적으로 서버와 통신할 수 있는 방법들을 묶어서 Ajax라고 한다. AJAX가 나오기 이전에는 브라우저 주소창에 특정 URL을 입력하거나, <a>태그 혹은 <form> 태그를 이용해야 했었다. 이것을 ActiveXObject(XMLHttpRequest)라고 불렀다.

이러한 방식은 데이터의 일부만 필요하더라도 HTML 파일 전체를 전송해야 했기에 비효율적이었고 HTML 자체가 교체되는 방식이기에 화면이 번쩍이는 문제가 존재했다고 한다.

동기 vs 비동기

앞에서 비동기라는 말을 했는데 이것이 무엇인지 조금더 알아보자.

동기는 기본적인 코드의 실행 방법이라고 생각하면 된다. 위에서 부터 순서대로 실행된다.

비동기는 순서대로가 아닌 실행 시간이 오래걸릴 것 같은 코드는 따로 빼서 실행시키고 다른 코드는 기존의 방식대로 실행시키는 등 병렬적으로 코드를 실행하는 방법이라고 할 수 있겠다.

console.log(1);
// setTimeout으로 콜백함수가 일정시간 뒤에 실행하도록 코드를 작성합니다. 순서대로 실행되지 않습니다.(비동기적으로 실행). 이러한 비동기 실행 코드는 setInterval, addEventListener 와 같은 함수들이 있습니다.
setTimeout(() => console.log(2), 100);
[3, 4, 5].forEach(i => console.log(i));
console.log(6);

위의 코드는 1을 찍고 2는 0.1초 뒤에 실행하도록 하고 3, 4, 5, 6을 찍고 2가 출력되는 비동기 코드이다.

XMLHttpRequest

서버와 비동기 통신을 가능하게 하는 여러 기능들을 가진 자바스크립트 객체이다. 최근에는 잘 사용하지 않고 뒤에서 나오는 fetch를 사용한다고 한다.

// XHR 객체를 생성합니다.
const requestObj = new XMLHttpRequest();
requestObj.open('GET', 'url'); // 요청을 초기화합니다. 통신방법과 요청을 발신할 대상의 주소를 전달합니다.
requestObj.onreadystatechange = () => { // readystate 가 변화하면 실행되는 이벤트리스너 입니다.
		// readystate : 요청을 보내는 클라이언트의 상태를 의미합니다.
    // readystate의 종류
    // 0 (UNSENT) - XHR 객체가 생성되었지만 아직 초기화되지 않았습니다.
    // 1 (OPENED) - open()함수가 호출되어 요청이 초기화되었습니다.
    // 2 (HEADERS_RECEIVED) - send()함수가 호출되었습니다.
    // 3 (LOADING) - 데이터를 다운받는 중 입니다.
    // 4 (DONE) - 통신이 완료되었습니다.
    if (requestObj.readyState == 4 && requestObj.status == "200") {

        const result = requestObj.responseText;

    }
};
requestObj.send(); // 서버로 요청을 보냅니다. send 메소드가 실행되어야만 우리가 위에서 설정한 내용들이 의미를 가지게 됩니다.

여기서 readyStatestatus 는 혼동이 올 수 있는데 피자 배달 예시를 들면 이해가 쉽다. readyState는 피자를 배달하는 사람이 배달 완료인지, 배달 중인지 추척하는 것이다. status는 피자가 도착하고 올바르게 만들어졌는지, 내 피자가 맞는지 확인하는 과정이라 보면 된다.

아, 그리고 자바스크립트의 &&(and)연산에 대해서도 짚고 넘어가겠다. 이러한 and 연산은 둘다 참이면 1이고 하나라도 거짓이면 거짓이고.. 이렇게 생각하기 쉽다. 그렇지만 이렇게 생각하면 이 and가 1줄에 여러개 올 때 잘못된 풀이가 된다.

따라서 자바스크립트의 &&는 두 값이 참이면 뒤의 값을 반환한다고 생각하는게 좋다. 또는 처음 만나는 거짓 같은 값(falsy)을 반환한다.

callback 지옥

Ajax는 기본적으로 비동기적으로 서버와의 통신을 처리하기에 Ajax와 기존의 동기식 코드를 함께 작성하면 코드의 실행순서에 문제가 발생한다. 자바스크립트의 엔진은 비동기 코드가 끝날때까지 다른 코드의 실행을 멈추지 않기 때문이다.

// sudo코드
const result = 비동기통신함수(); // undefined

const result2 = 비동기통신함수2();	// undefined

const total = result + result2; // NaN

// 이런 방식은 불가능합니다. result와 result2에 무슨 값이 들어있을지 생각해보세요.

result 비동기 함수와 result2 비동기 함수가 채 끝나기도 전에 total의 값이 출력되어 위의 결과가 나온다.

let result;
function xhrRequest() {

    const requestObj = new XMLHttpRequest();
    requestObj.open('GET', 'message.txt');
    requestObj.onreadystatechange = () => {
        if (requestObj.readyState === 4 && requestObj.status === 200) {

            result = requestObj.responseText;
            console.log(result); // 콘솔에 무엇이 찍히는지 확인해봅시다.
        }
    };
    requestObj.send();
}

xhrRequest();
console.log(result); // 콘솔에 무엇이 찍히는지 확인해봅시다.

Ajax는 비동기 방식이기에 요청을 보내고 바로 결과를 출력하면, 아직 요청이 완료되지 않았기에 예상과 다른 결과가 출력된다.

그렇기에 통신이 끝난 다음에야 다음 함수가 실행되도록 콜백함수로 코드를 작성해야 한다.

const total = 비동기통신함수( 
        input,
        통신함수의결과를가공하는함수1 ( 
            result, 
            비동기통신함수2(
                통신함수의결과를가공하는함수2(
                    result, 
                    result2
                )
            ) 
        ) 
    );

// 이렇게 비동기 함수가 끝나기 전에 중간 중간에 필요한 콜백함수를 실행시키며 사용할 수 밖에 없었습니다.

부득이하게 콜백 함수를 사용하는데 이게 많아지면 코드의 가독성이 저하되고 문제 해결이 어려운 단점이 존재한다.

피드백

1만 시간의 법칙이라는 페이지를 강사님과 같이 만들어 보았다. 혼자서도 해보았지만 쉽지는 않았는데 다른 분들 코드랑 강의 등을 보면서 한번 더 해봐야 겠다. 어렵지만 포기하지 말자. 할 수 있다

profile
익숙해지기 위해 기록합니다

0개의 댓글