이 글은 '이웅모'님의 '모던 자바스크립트 Deep Dive' 책을 통해 공부한 내용을 정리한 글입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다.
fetch
함수는 XMLHttpRequest
객체와 마찬가지로 HTTP 요청 전송 기능을 제공하는 클라이언트 사이드 Web API다.
fetch
함수는 XMLHttpRequest
보다 사용이 간단하고 프로미스를 지원하기 때문에 비동기 처리를 위한 콜백 패턴의 단점에서 자유롭다.
// 요청을 전송할 URL
// HTTP 요청 메서드, 요청 헤더, 페이로드 등을 설정
const promise = fetch(url, [, options]);
// example
const promise = fetch('https://seeen.com/todos/1').then(res=>console.log(res));
fetch
함수는 HTTP 응답을 나타내는 Response 객체를 래핑한 프로미스를 반환하므로 후속 처리 메서드 then 을 통해 프로미스가 resolve한 Response 객체를 전달받을 수 있다.
Response.prototype에는 Response 객체에 포함되어 있는 HTTP 응답 몸체를 위한 다양한 메서드가 존재한다.
특히, Response.prototype.json
메서드는 Response 객체에서 HTTP 응답 몸체를 취득하여 역질렬화한다.
const url = 'https://seeen.com/todos/1'; // 404라고 가정
// 잘못된 에러 핸들링
fetch(url)
.then(console.log) // 이 부분이 출력
.catch(console.error);
// 제대로 된 에러 핸들링
fetch(url)
.then((res)=>{
if(!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error); // 이 부분이 출력
fetch 함수가 반환하는 프로미스는 오프라인 등의 네트워크 장애나 CORS 에러에 의해 요청이 완료되지 못한 경우에만 프로미스를 reject 한다.
즉, 404 Not Found
와 같은 HTTP 에러가 발생해도 에러를 reject 하지 않고 불리언 타입의 ok 상태를 false
로 설정한 Response 객체를 resolve한다.
참고로 axios는 모든 HTTP 에러를 reject하는 프로미스를 반환한다.
아래의 메서드 예시는 request
객체를 참조한다.
const request = {
get(url) {
return fetch(url);
},
post(url, payload) {
return fetch(url, {
method: 'POST',
headers: { 'content-Type' : 'application/json' },
body: JSON.stringify(payload)
});
},
put(url, payload) {
return fetch(url, {
method: 'PUT',
headers: { 'content-Type' : 'application/json' },
body: JSON.stringify(payload)
});
},
patch(url, payload) {
return fetch(url, {
method: 'PATCH',
headers: { 'content-Type' : 'application/json' },
body: JSON.stringify(payload)
});
},
delete(url) {
return fetch(url, { method: 'DELETE' });
}
};
request.get('http://seeen.com/todos/1')
.then(res => {
if (!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error);
request.post('http://seeen.com/todos/1', {
userId : 152
title : 'JS'
completed : false
}).then(res => {
if (!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error);
request.put('http://seeen.com/todos/1', {
userId : 152
title : 'TS'
completed : true
}).then(res => {
if (!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error);
request.patch('http://seeen.com/todos/1', {
completed : true
}).then(res => {
if (!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error);
request.delete('http://seeen.com/todos/1')
.then(res => {
if (!res.ok) throw new Error(res.statusText);
return res.json();
})
.then(console.log)
.catch(console.error);