JavaScript의 라이브러리 중 하나이며,
Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml의 약자)이다.
AJAX는 JavaScript를 사용한 비동기 통신, 클라이언트와 서버 간에 XMLHttpRequest 데이터를 주고받는 기술이라고 할 수 있다.
대부분의 웹 브라우저에서는 서버로부터 데이터를 요청하는 XML 객체들을 내장하고 있다.
XMLHttpRequest를 이용하면 웹 페이지를 전부 로딩하고도 서버로부터 데이터를 요청하거나 전송받을 수 있으며, 웹 페이지를 전부 로딩하지 않고도 일부만을 갱신하는 게 가능해진다.
프로미스는 자바스크립트 비동기 처리에 사용되는 객체다.
여기서 자바스크립트의 비동기 처리란 ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’을 의미한다.
기본 구조
function getData(callbackFunc) {
$.get('url 주소/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
프로미스 적용
function getData(callback) {
// new Promise() 추가
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
// 데이터를 받으면 resolve() 호출
resolve(response);
});
});
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
// resolve()의 결과 값이 여기로 전달됨
console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의
상태(states)
다. 여기서 말하는 상태란 프로미스의 처리 과정을 의미한다. new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.
Pending(대기)
new Promise(function(resolve, reject) {
// ...
});
Fulfilled(이행)
new Promise(function(resolve, reject) {
resolve();
});
Rejected(실패)
new Promise(function(resolve, reject) {
reject();
});
실패 했을 때 처리
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
여러 개의 프로미스 연결하기 (Promise Chaining)
function getData() {
return new Promise({
// ...
});
}
// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
.then(function(data) {
// ...
})
.then(function() {
// ...
})
.then(function() {
// ...
});
프로미스 에러 처리는 가급적 catch()를 사용
// then()의 두 번째 인자로는 감지하지 못하는 오류
function getData() {
return new Promise(function(resolve, reject) {
resolve('hi');
});
}
getData().then(function(result) {
console.log(result);
throw new Error("Error in then()"); // Uncaught (in promise) Error: Error in then()
}, function(err) {
console.log('then error : ', err);
});
fetch 매서드는 JavaScript에서 서버로 네트워크 요청을 보내고 응답을 받을 수 있도록 해주는 매서드이다.
XMLHttpRequest와 비슷하지만 fetch는 Promise를 기반으로 구성되어 있어서 더 간편하게 사용할 수 있다는 차이점이 있다.
기본 구조
fetch(url)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
기본적인 구조와 동작은 Promise 객체와 동일하다.
then에서 응답 객체 res를 받고, catch에서 에러 요청이 발생했을 때, 에러를 받는다.
요청 정보 파라미터
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(res => {
console.log(res);
})
.catch(error => console.log(error));
- method : HTTP method와 동일하며 요청 방식을 나타낸다. (GET, POST, PUT, DELETE 등)
- headers : 요청 헤더에 대한 정보를 나타낸다.
- body : 요청을 보내는 데이터를 나타낸다. 여러 가지 자료형을 대입할 수 있다.
fetch 파라미터로 직접 입력
하기도 하지만 주로 객체 변수에 저장해서 대입하는 방식
으로도 사용한다.
let obj = {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
}
fetch(url, obj)
.then(...)
POST 요청 보내고 응답받기
fetch(url, {
method: 'POST',
body: JSON.stringify({ name: "hello!" })
})
.then(res => {
if (res.status === 200) {
res.text().then(text => console.log(text)
}
else {
console.log(res.statusText)
}
})
.catch(err => console.log(err))
- POST로 body안에 데이터를 넣고, 요청을 보내주면 응답 객체 res를 받게 되는데 res 안에는 응답에 관한 정보가 존재한다.
- status는 요청이 성공인지 실패인지를 판별할 수 있게 해주는 요소이다.
- 또 응답에 대한 내용은 res.text()를 통해 확인할 수 있다.
- text() 외에도 arrayBuffer, blob, json, formData 등의 메서드를 사용하여 값을 볼 수도 있다.
- GET, PUT, DELETE 요청도 같은 방식으로 보낼 수 있다.
async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법이다. 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.
async & await 기본 문법
async function 함수명() {
await 비동기_처리_메서드_명();
}
- 먼저 함수의 앞에 async 라는 예약어를 붙인다.
- 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙인다. (비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작함)
- 프로미스 객체를 반환 하는 것은 Axios 등 프로미스를 반환하는 API 호출 함수가 있다.
function fetchItems() {
return new Promise(function(resolve, reject) {
var items = [1,2,3];
resolve(items)
});
}
async function logItems() {
var resultItems = await fetchItems();
console.log(resultItems); // [1,2,3]
}
Jquery에서 사용 예제
// HTTP 통신 동작을 모방한 코드
function fetchItems() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
var items = [1,2,3];
resolve(items)
}, 3000);
});
}
// jQuery ajax 코드
function fetchItems() {
return new Promise(function(resolve, reject) {
$.ajax('domain.com/items', function(response) {
resolve(response);
});
});
}
await를 사용하지 않았다면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백 함수나 .then()등을 사용해야 했을 것이다.
하지만 async await 문법 덕택에 비동기에 대한 사고를 하지 않아도 된다.
async & await 실사용 예제
function fetchUser() {
var url = 'https://jsonplaceholder.typicode.com/users/1'
return fetch(url).then(function(response) {
return response.json();
});
}
function fetchTodo() {
var url = 'https://jsonplaceholder.typicode.com/todos/1';
return fetch(url).then(function(response) {
return response.json();
});
}
async function logTodoTitle() {
var user = await fetchUser();
if (user.id === 1) {
var todo = await fetchTodo();
console.log(todo.title); // delectus aut autem
}
}
- fetchUser()를 이용하여 사용자 정보 호출
- 받아온 사용자 아이디가 1이면 할 일 정보 호출
- 받아온 할 일 정보의 제목을 콘솔에 출력
async & await 예외 처리
async function logTodoTitle() {
try {
var user = await fetchUser();
if (user.id === 1) {
var todo = await fetchTodo();
console.log(todo.title); // delectus aut autem
}
} catch (error) {
console.log(error);
}
}
코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있다. 발견된 에러는 error 객체에 담긴다.
출처
https://joshua1988.github.io/web-development/javascript/js-async-await/
https://ljtaek2.tistory.com/130