Ajax를 위해 이해해야하는 것들
- Client - Sever
- HTTP
- JSON
- 비동기
둘다 기본적으로 한개를 고치는 것. 하나안에 id content complte가 있고
PUT - id를 제외한 전부 다 고치면
PATCH - 여기서 content나 complete를 고치면
Ajax를 이용한 실습
<!DOCTYPE html>
<html lang="en">
</head>
<body>
<pre class="result"></pre>
<script>
const $result = document.querySelector('.result');
const render = content => ( $result.innerHTML = JSON.stringify(content, null, 2) );
const ajax = (method, url, callback, payload) => { // payload는 옵션이기때문에 맨 뒤쪽 인자로 써준다.
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json'); // get은 이작업을 안해줘도 상관없음.
xhr.send(JSON.stringify(payload)); // 보내는 것은 위 4줄이 끝! 비동기 처리부분이 아님.
// respose가 필요한 경우 여기부터 시작
xhr.onreadystatechange = () => { // 이벤트 프로퍼티 방식은 이벤트 앞에 on을 붙여준다! 예를들면 click앞에 onclick / 이 함수만 비동기처리부분임 이 안에서 에러나면 잡기 힘듬.
// console.log(xhr.readyState); // 함수 내부에서는 할일을 적어주면 된다. readyState는 현재 상태
if (xhr.readyState !== XMLHttpRequest.DONE) return; // 4번(DONE은 상수)이 아니면 아래쪽에 최종적으로 할일을 적어준다.
if (xhr.status >= 200 && xhr.status < 400) { // status는 http 상태 코드, 200은 OK | 201은 POST가 OK | 404 리소스를 요청했는데 자료가 없는경우
// request가 제대로 되서 제대로 response를 받은 경우 = success
callback(JSON.parse(xhr.response));
} else {
// fail
// 실무에서는 파일에다가 시간정보, 담당자번호 등 다양한 정보를 데이터베이스에 저장
// console.error('eroor...');
}
};
};
try{
setTimeout(() => {throw Error('error'); }, 1000);
} catch(e) {
console.error('error');
console.log(e);
}
// try{
// ajax('GET', 'http://localhost:3000/todos/3', render);
// } catch(e){
// console.error('error');
// console.error(e);
// }
// ajax('GET','http://localhost:3000/todos');
// ajax('POST', 'http://localhost:3000/todos', render, {
// id: 4, content: "Angular", completed: true
// });
// ajax('DELETE', 'http://localhost:3000/todos/4', render);
// ajax('PUT', 'http://localhost:3000/todos/3', render, {
// id: 3, content: "React", completed: false
// });
// ajax('PATCH', 'http://localhost:3000/todos/3', render, {completed: true});
</script>
</body>
</html>
Promise를 사용한 실습예제
<!DOCTYPE html>
<html lang="en">
</head>
<body>
<pre class="result"></pre>
<script>
const $result = document.querySelector('.result');
const render = content => ($result.innerHTML = JSON.stringify(content, null, 2));
const promiseAjax = (method, url, payload) => { // payload는 옵션이기때문에 맨 뒤쪽 인자로 써준다.
return new Promise((resolve, reject) =>{ // callback을 promise로 호출 , resolve는 성공시 호출 , 실패는 reject
// 실패하면 실패한 이유를 reject로 호출
// Promise는 4가지 상태를 가지고 있다. 그중에 성공이냐 실패냐만 알면된다.
// 성공했으면, then을 쓴다. 실패했으면, catch를 부른다.
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json'); // get은 이작업을 안해줘도 상관없음.
xhr.send(JSON.stringify(payload)); // 보내는 것은 위 4줄이 끝! 비동기 처리부분이 아님.
// respose가 필요한 경우 여기부터 시작
xhr.onreadystatechange = () => { // 이벤트 프로퍼티 방식은 이벤트 앞에 on을 붙여준다! 예를들면 click앞에 onclick / 이 함수만 비동기처리부분임 이 안에서 에러나면 잡기 힘듬.
// console.log(xhr.readyState); // 함수 내부에서는 할일을 적어주면 된다. readyState는 현재 상태
if (xhr.readyState !== XMLHttpRequest.DONE) return; // 4번(DONE은 상수)이 아니면 아래쪽에 최종적으로 할일을 적어준다.
if (xhr.status >= 200 && xhr.status < 400) { // status는 http 상태 코드, 200은 OK | 201은 POST가 OK | 404 리소스를 요청했는데 자료가 없는경우
// request가 제대로 되서 제대로 response를 받은 경우 = success
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.status);
}
};
});
};
(async function () {
const res = await promiseAjax('GET', 'http://localhost:3000/todos/');
console.log(res);
}());
// promiseAjax('GET','http://localhost:3000/todos/')
// .then(render) // 콜백을 2개 받는다. 첫번째는 성공 콜백 / 두번째는 실패 콜백 대부분 성공 콜백만 준다 (통상적으로)
// // .then을 계속 써줘서 하는 것 promise 체인이라고 한다. 순서대로 코드를 작성 가능하다.
// .catch(console.error());
</script>
</body>
</html>
현업에서는 비동기 처리를 위하여 Promise를 쓰던가 , async await를 쓰던가. 둘중에 하나로 쓴다.
Promise는 총 4가지 상태를 갖지만, 아래 2가지가 중요.
fulfilled | 비동기 처리가 수행된 상태 (성공) | resolve 함수가 호출된 상태 |
rejected | 비동기 처리가 수행된 상태 (실패) | reject 함수가 호출된 상태 |
then은 promise를 반환한다.
const url = 'http://jsonplaceholder.typicode.com/posts';
// 포스트 id가 1인 포스트를 검색하고 프로미스를 반환한다.
promiseAjax('GET', `${url}/1`)
// 포스트 id가 1인 포스트를 작성한 사용자의 아이디로 작성된 모든 포스트를 검색하고 프로미스를 반환한다.
.then(res => promiseAjax('GET', `${url}?userId=${JSON.parse(res).userId}`))
.then(JSON.parse)
.then(render)
.catch(console.error);
then then then이 이어짐 = 프로미스 체이닝
이 동작이 가능한 이유는 then이 프로미스를 리턴해주기 때문에 가능하다.
에러는 catch로 잡는다.
promise는 new를 사용하기 때문에 생성자 함수이다.
대부분의 생성자 함수는 정적 메소드를 가지고 있다. ( ex ) Array.isarray 처럼 )
정적 메소드 들
Promise.resolve
Promise.reject
Promise.all : 일반적으로 인수로 배열을 준다. 배열안에는 promise객체를 담는다. 그래서 all은 죄다 실행하고 결과값을 배열에다가 담아준다.
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log) // [ 1, 2, 3 ]
.catch(console.log);
3초 걸린다. all안에 쓴 배열 순서대로 결과가 나온다.
Promise.all([
1, // => Promise.resolve(1)
2, // => Promise.resolve(2)
3 // => Promise.resolve(3)
]).then(console.log) // [1, 2, 3]
.catch(console.log);
프로미스 객체가 아니면, 기본적으로 프로미스 객체로 바꿔준다.
const githubIds = ['jeresig', 'ahejlsberg', 'ungmo2'];
Promise.all(githubIds.map(id => fetch(`https://api.github.com/users/${id}`)))
// [Response, Response, Response] => Promise
.then(responses => Promise.all(responses.map(res => res.json())))
// [user, user, user] => Promise
.then(users => users.map(user => user.name))
// [ 'John Resig', 'Anders Hejlsberg', 'Ungmo Lee' ]
.then(console.log)
.catch(console.log);
all안에 기입한 순서대로 동작한다.
Promise.race
Promise.race([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log) // 3
.catch(console.log);
레이스는 경쟁시킨다. 먼저 처리된게 먼저 나오고 끝! (1등만 나옴)
첫번째 발생한 에러만 잡고 끝.
** 깨알상식 : 존레식(jeresig) - jquery 만든사람 / ahejlsberg(아일스 버그) : c#, typescript 만든사람
'패스트캠퍼스 > 수업내용정리' 카테고리의 다른 글
2019-06-04 mongoDB, Sass (0) | 2019.06.04 |
---|---|
2019-06-03 npm, babel, webpack (0) | 2019.06.03 |
2019-05-29 비동기식 처리 모델과 Ajax , REST API 등 (0) | 2019.05.29 |
2019-05-22 클래스, 모듈, DOM (0) | 2019.05.22 |
2019-05-20 배열고차함수 , 정규표현식, 화살표함수 (0) | 2019.05.20 |