오랜만에 TIL을 작성하는 것 같습니다.
최근에는 학습보단 프로젝트 위주로 진행하는 바람에 딱히 포스팅할 주제가 생각이 나지 않았던것 같아요..! 물론 프로젝트를 진행하면서 학습하는 부분도 많았지만, 마음이 급했는지 당장 게시글로 옮길 엄두가 안나서 최근 오랫동안 게시글을 쓰지 못했습니다.
최근에 졸업을 하게 되었는데, 야구선수로써 약 13년을 보내고, 개발자가 되고자 처음 편입학 했을떄가 생각나네요..! 힘든 시간이였지만 나름 재밌게 생활한 것 같습니다.
나중에 졸업에 관련된 포스팅도 꼭 하고싶네요..! TMI는 여기까지
오늘은 프로젝트를 진행하며 유용하게 사용할 수 있는 XMLHttpRequest
에 대해서 게시하고자 합니다. 자바스크립트를 이용하신 분들은 Fetch API
도 많이 이용하시겠지만, 아직까지 조금 더 대중적인 API를 이용하여 작성했습니다.
XMLHttpRequest
반환 값 사용하기웹 개발을 하다보면AJAX
를 참 많이 이용하는데요, 여기서 맨 앞에 A는 Asynchronous(비동기)
를 의미합니다. 비동기에 대한 특성은 쉽게 생각하면 아주 간단한데요, 동기 방식은 코드의 응답 결과를 받을 때 까지 기다리는 것이고, 비동기 방식은 코드의 응답 결과를 기다리지 않고 다음 동작을 먼저 수행하고 있는 것입니다.
이러한 비동기는 좋은 퍼포먼스를 낼 수 있게 도와주곤 하지만 개발자 입장에서 코드를 복잡하게 만들고, 구현하기 까다로워 지는 특성이 있습니다.
비동기에 대해선 여기에 제가 잘 포스팅 해놓았으니 참고하시면 좋을 것 같습니다.
비동기에서 초보개발자(저포함..)가 흔히 겪을 수 있는 실수는 아래와 같습니다.
function foo() {
let result;
$.ajax({
url: '...',
success: function(response) {
result = response;
// return response; // <- I tried that one as well
}
});
return result;
}
let result = foo(); // undefined
맨 아래 변수 result
는 왜 undefined
일까요? 코드를 살펴보면 URL
을 작성하고 요청을 보내면 response
값을 전달 받습니다. 물론 URL
에 포함되어 있는 로직은 문제가 없습니다.
이유는 Asynchronous
이기 떄문입니다. 위에서 간단하게 정의하였지만 비동기 통신은 응답을 기다려주지 않습니다. 즉, URL
로 요청을 보내고, 응답을 기다려주지 않고 return result
가 실행될 것입니다.
조금 더 간단하게 설명하자면, 요청에 대한 응답결과를 받기전에 foo
함수가 return
된 것이죠.
그럼 이러한 문제는 어떻게 해결하면 될까요?
참고문헌에서는 두가지 방법이 있다고 합니다.
1. AJAX
를 Synchronous
하게 호출한다.
첫번째 방법은 MDN에서 권장하지 않는 방법입니다. 아주 당연한 이유 때문인데요..!
AJAX
에 맨 앞 A
는 Asynchronous
(비동기) 입니다. 만약 AJAX
를 Synchronous
하게 호출한다면 AJAX
가 아니라 SJAX
가 되버리는 것이죠..
이러한 방법은 브라우저가 서버의 응답을 받을 때 까지 동작을 멈추게 만들고 그로인한 성능저하가 발생하게 됩니다. 예제 코드가 있지만, 사용할 필요가 전혀 없기에 포함하지 않도록 하겠습니다..!
callback
을 받을 수 있게 코드를 다시 작성.이 방법은 현실적인 방법이라고 할 수 있습니다. 아래 코드를 보면,
foo(function(result) {
// 결과에 따라 달라지는 코드
});
위 같은 방법을 이용할 수 있는데요, 위 방식은 foo
라는 함수를 호출하는데 인자로 함수를 넣는 것입니다. 이렇게 작성하게 되면 아래와 같은 방식으로 Response
값을 얻을 수 있습니다.
function foo(callback) {
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4) { // request is done
if (httpRequest.status === 200) { // successfully
callback(httpRequest.responseText); // we're calling our method
}
}
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();
}
foo(function (result) {
document.body.innerHTML = result;
});
이 코드를 보면 foo
함수를 호출하고 인자로 함수가 들어갑니다. foo
함수는 호출 될 것이고,foo
함수 내부에 로직을 수행할 것입니다. foo
함수는 파라미터 하나가 존재하는데요, 이는 아래 foo
호출 문에서 인자로 함수를 정의하였으므로, 중간에 callback
이라는 함수 호출문 형식으로 로직을 짤 수 있습니다.
결과적으로 callback
의 함수 호출문의 인자로 응답 결과를 넣게 되고 이는 맨 아래 foo
함수 호출문에 인자로 들어있는 함수의 파라미터 값이 될 것입니다.
그럼 아래 foo
함수 호출문에서 인자로 정의한 함수 내에서 result
값을 이용하여 응답을 받을 수 있습니다.