=> 서버와 통신하는 기술!!
=> 서버와 비동기적으로 데이터를 주고받는 자바스크립트 기술
=> 웹페이지의 이동없이 필요한 데이터만 전송하는 기술
=> AJAX 덕분에 새로고침없이 너튜브에서 해당 페이지 영상이 재생되는 거임!!
=> 일반적인 경우, 데이터 처리는 요청 순서대로 처리하지만, AJAX는 순차적으로 진행하지 않는다. 이런 방식을 비동기 방식이라고 한다.
=> 이러한 비동기 통신 방법을 알고 있다면, 지구 반대편에 있는 다른 컴퓨터와도 데이터를 주고 받을 수 있다.
=> 대부분의 비동기 작업용 함수는 Promise 객체를 return한다.
=> promise 객체 : 비동기 작업 처리용 표준 인터페이스
=> 물론, 아직까지 Promise를 지원하지 않는 라이브러리도 은근 있다. 그런 경우에는 "아!! 이 분들이 여유롭게 일하는 구나..."라고 좋게 넘기면 된다.
ex)
나 : ( 너튜브에서 ) 나 이 동영상 보고 싶어요. 동영상 보내주세요~
너튜브 서버 : ㅇㅇ 보내준다!!
이 때, 서버에 원하는 데이터를 요구하는 방식은 다음과 같다.
그럼, GET 요청은 어떻게 하는가??
방법 1. 주소창에 해당 URL 붙여넣기
방법 2. 버튼으로 (form
) 으로 URL을 감싸서, 클릭시 해당 URL로 이동 시키기
방법 3. AJAX로 GET요청 날리기
=>form
의 경우, 클릭시 자동으로 새로고침이 일어나는데, 이 방법은 새로고침 없이 서버에 GET 요청을 하는 JS 코드
=> 즉, 새로 고침이 일어나는 2번 방법보다 부드럽게 동작하는 싸이트를 만들 수 있다.
JS로 AJAX 요청을 할 수 있는 방법은 크게 3가지가 있다.
1. XMLHttpRequest 객체
이미지 출처 - 코딩애플
=> 하지만, 이 방식은 코드가 너무 길고( =가독성이 떨어짐 ), 복잡해서 잘 쓰지 않는다.
2. fetch API 방식 ( ES06 )
상하단 이미지 출처 - 코딩애플
=> 에러 처리까지 포함하면, 데이터 하나 받아오는데, 길고 복잡해져서, 다른 라이브러리같은 거를 쓰는 경우도 많다.
3. 외부 라이브러리 방식
$.ajax()
함수가 기본적으로 있어서 그것을 쓰면 된다.하지만, 이번 스프린트는 fetch를 권장하기 때문에 fetch에 대해서 좀 더 알아보고 사용해보도록 하자!!
axios가 상대적으로 간결한 코드로 같은 기능을 수행하지만, 그럼에도 fetch를 사용해야 되는 경우가 있다.
장점
- 구형 브라우저를 지원한다.
- 크로스 브라우징에 신경을 많이썼기에 브라우저 호환성이 뛰어나다.
- 응답시간 초과를 설정하는 방법이 있다
=> response timeout 처리 방법이 있다. ( fetch에는 존재하지 않는 기능 )- JSON 데이터 자동변환이 가능하다.
node.js
에서의 사용이 가능하다- request aborting (요청취소)이 가능하다
catch
에 걸렸을 때,.then
을 실행하지 않고,.console
창에 해당 에러 로그를 보여준다.- return 값은 Promise 객체 형태이다.
=> promise 기반으로 상대적으로 다루기가 쉽다.
단점
- 모듈 설치를 해줘야한다.
- 자바스크립트 내장 라이브러리이기 때문에 import하지 않고 사용할 수 있다.
- 라이브러리의 업데이트에 따른 에러 방지가 가능하다 ( React Native의 경우 업데이트가 잦아서 라이브러리가 쫓아오지 못하는 경우가 많은데, fetch의 경우 이를 방지할 수 있다.)
- return 값은 Promise객체 형태이다.
- 네트워크 에러가 발생했을 때 기다려야 한다. ( response timeout API가 없음!! )
- 지원하지 않는 브라우저가 있다.
=> internet explorer의 경우에는 fetch를 지원하지 않는 버전도 존재한다. ( 즉, 브라우저 호환성이 상대적으로 떨어진다.)- axios에 비해 상대적으로 기능이 부족하다.
일반적으로, 프레임워크(react js,vue js 등)를 다룰때에는 Axios를 사용한다. Axios는 크로스 브라우징에 신경을 많이 쓴 모듈인게 눈에 보이며, 기능 또한 fetch보다 다양하다.
하지만, react-native에서는 fetch를 사용하는 것이 더 좋다. react-native의 경우 아직 안정화 된 프레임워크가 아니다. 즉, 지속적인 version update가 빠르게 진행되고 있으며, axios가 이를 반영하지 못할 경우 생각지 못한 에러가 발생할 수 있다.
결론은 react-native에서는 안정화 측면에서. fetch를 사용하는 것이 더 좋다.
부트 캠프 교육 엔지니어님께서는 " Ajax tool은 가급적 모두 다 사용해보시는 것을 추천드립니다. 러닝 커브가 전혀 존재하지 않을 정도로 fetch와 Axios의 코드 차이가 미미하기도 하고 사실 크게 부담느낄정도로 장단점이 극명하지도 않기 때문이죠. " 라고 하신다.
대표적인 3가지 용어는 알아두고 있으면 좋다.
pending : "수행 중" 이라는 실행 상태
fullfilled : 성공적인 완료 ( 데이터를 성공적으로 받아옴 )
rejected : 실패 했다. ( 데이터를 못 받아옴 )
ex) [[PromiseState]]: "fulfilled"
let res = fetch("hi.txt").then (function (response) {
response.text().then( function (text) {
console.log(text);
} )
})
만약, hi.txt
를 받아오는데 시간이 걸린다면?? 데이터를 받아올 때까지 기다리고만 있어야 하나??
이런 잠재적인 시간 낭비를 막기위해서, fetch는 한가지 약속된 함수를 제공해주는데, 바로 .then( )
이다.
내가 너가 원하는 data를 받아오는데 시간이 걸릴 수 있으니까
너가 .then() 안에다가 실행 결과를 받을 수 있는 함수만 적어주면, 나는 실행이 완료 되는 데로 then 함수 안에 있는 바로 콜백 함수 안 에다가 실행 결과를 넣어줄게!!
바로 성공의 결과를 받아줄 수 있는 함수를 프로그래머들은 콜백 함수 라고 부른다. => 호출했을 때, 그 결과를 돌려받는 함수
그리고 이 콜백 함수의 첫번째 매개 변수에 "상태"를 저장해주도록 약속이 되어 있다.
위 코드의 경우, response는 성공 실패에 대한 결과를 가지고 있는 중요한 객체이다.
그리고 response와 이어져 있는 text() 라는 함수는 그 결과를 문자열로 바꿔주는 함수이다.
그리고 그 변형된 함수를 then() 이라는 콜백 함수에 짚어 넣어서 그 실행 결과를 안 쪽에 있는 익명 함수에 받아주는 원리이다.
// 출력 순서 : 2 => text => 1
let promise = fetch("hi.txt").then(function (res) {
console.log(1);
res.text().then(function (result) {
console.log(result);
});
});
console.log(2);
// 출력 순서 : 2 => 1 => json
let promise2 = fetch("https://yts.mx/api/v2/list_movies.json").then(
function (res) {
console.log(1);
res.json().then(function (result) {
console.log(result);
});
}
);
console.log(2);
- WHY??
데이터를 받아오는데, 시간이 얼마나 걸릴지 모르니까 .then()
안에 성공에 대한 결과만 넣어주고, 기다리지 않고, 바로 프로그램 실행이 그 다음으로 넘어가게 된다.
그래서, 나중에 복잡한 fetch()
들이 얽혀있으면, 실행 순서가 꼬이게 되기 때문에, 코드 사용 순서에 주의해야 한다.
// 버전 1
fetch("../hi.json").then(function (res) {
res.json().then(function (result) {
console.log(result.name);
console.log(result.id);
});
});
위의 코드를 좀 더 가독성이 좋은 코드로 변경해보자!
// 버전 2
fetch("../hi.json")
.then(function (res) {
// then의 익명 함수에 대한 return 값이고 이게 그 다음 then으로 넘어간다.
return res.json();
})
.then(function (data) {
return data.name;
})
.then(function (final) {
console.log(final);
});
프로그래머들은 약속을 하는데, 받아오는 data에 내 맘대로 적고 싶은데로 막 적어놓으면, 필요한 값을 가지고 나왔을 때, 중요한 값만 뽑아서 사용하기 어렵다.
그래서, 그 문서 안에다가 data를 사용하기 쉽게, JS 객체 형식인 JSON이라는 형식으로 주고 받도록 되어있다.
fetch("https://yts.mx/api/v2/list_movies.json")
.then(function (res) {
// then의 익명 함수에 대한 return 값이고 이게 그 다음 then으로 넘어간다.
return res.json();
})
.then(function (final) {
console.log(final);
});
JSON 객체에 대한 더 자세한 설명은 과거 필자가 정리한 글을 확인하길 바란다.
API에 대한 자세한 설명은 필자가 과거에 쓴 글을 확인바랍니다.
API => 잘 만들어진 기능에 사용 방법!!!
API 를 활용해라
=> 잘 만들어진 기능에 사용 방법을 제공해줄 테니까, 그 방법을 보고 잘 연결해서 사용해!!
ex)
해당 싸이트에 접속해보면, API를 사용하기 위한 문서를 제공한다.
YTS.mx API 문서
를
링크된 싸이트에서 Endpoint 파트를 보면, 데이터를 어떤 형식으로 받을지 선택할 수 있다.
API가 두 시스템(어플리케이션)이 상호작용(소통) 할 수 있게 하는 프로토콜의 총 집합이라면,
Endpoint는 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL이라 할 수 있겠다.
fetch("https://yts.mx/api/v2/list_movies.json?sort_by=year&order_by=desc")
.then(function (res) {
if (res.status != 200) {
alert("서버와 통신에 실패했습니다.");
} else {
return res.json();
}
})
.then(function (final) {
console.log(final);
});
list_movies.json 이후로 ? 와 &로 이어져있는 것을 볼 수있는데, Parameters(매개 변수)를 활용할 수 있는 형식인 Query String이다.
쿼리스트링은 사용자가 웹프로그램으로 입력데이터를 전달하는 가장 단순하고 널리 사용되는 방법이다. 이 방법은 URL주소 뒤에 입력 데이터를 함께 제공하는 방법으로 다음과 같은 형식을 취한다.
// ? 로 URL 끝 부분에 붙여서 사용
// Parameter를 하나 더 추가하고 싶다면?? => & 로 이어주자
http:// hostname[:port]/folder/file?변수1=값&변수2=값2&변수3=값3
근데, 여기서 좀 헷갈렸던 게... 위의 path 부분( Path parameter )만으로 충분히 필요한 부분을 만들 수 있을 것같은데... 왜 구지 Query string이 필요한지 이해하지 못했다.
이제 이 필요성에 관해 짚고 넘어가고자 한다.
Path parameter와 Query string는 언제 사용되야 하는가??
- Path parameter
=>원하는 조건의 데이터들
혹은하나의 데이터
에 대한 정보를 받아올 때 적절
( 따로 정제되지 않은 데이터 가져올 때..! )
- Query string
=>filtering
,sorting
,searching
에 적절
간단하게 쓰고 넘어가려고 했는데, 미래에 다시 찾아볼 순간을 위해 대충 넘어갈 수 없다보니... 생각보다 글이 길어졌다.
Sprint 자체의 난이도는 크게 안 높았지만, 다양한 개념들을 배울 수있어서 알찼던 것같다.