###########################################################################
###########################################################################
11장. 비동기
###########################################################################
1. 동기 vs 비동기
가. 동기
function fun() {
"1출력"
fun2(); function fun2() {"2출력"} // 만약 1시간작업이라면?
"3출력"
}
fun();
실행결과:
1출력
2출력
3출력 // fun2() 가 끝난후에 출력됨
나. 비동기
function fun() {
"1출력"
fun2(); function fun2() {"2출력"} // 만약 1시간작업이라면?
"3출력
}
fun();
실행결과:
1출력
3출력
2출력 // fun2() 가 끝난후에 출력
2. 비동기 만드는 방법
가. Promise 객체 이용
- 문법: 함수를 작성할 떄 Promise 객체를 반환한다.
ex>
#일반함수
function fun() {
}
#비동기함수
function fun() {
// 성공시 호출함수: resolve
// 실패시 호출함수: reject
return new Promise(function(resolve, reject));
}
- 실제 구현
resolve 호출에 대한 처리: .then(function() {})
reject 호출에 대한 처리: .catch(function() {})
- then().then(). ... 체인 가능
나. async / await 키워드 이용 (*)
- 내부적으로 Promise 사용됨.
- 문법:
# 일반함수
function fun() {
}
# 비동기 함수
async function fun() {
"1출력"
/////////////
xxx = await fun2(); // await 함수가 실행이 끝날때까지
// fun() 실행을 중지시킴.
////////////
"2출력"
}
var result = fun(); // result 값이 Promise 객체이다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise1_생성</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// 비동기 함수 생성
function fun() {
// return new Promise(함수);
// return new Promise(function (성공호출, 실패호출) { });
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
});
}
var result = fun();
console.log("result: ", result);
console.log("end.");
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise2_메서드호출</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// 비동기 함수 생성
// 2. resolve, reject 함수 호출
function fun(status) {
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
if (status == "ok") {
resolve(); // 성공
} else {
reject(); // 실패
}
console.log("2");
});
}
var result = fun("ok");
console.log("result: ", result);
console.log("end.");
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise2_메서드호출2_처리구현</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// 비동기 함수 생성
// 2. resolve, reject 함수 호출
// 3. resolve 호출에 대한 처리작업: then() 사용.
// reject 호출에 대한 처리작업: catch() 사용.
function fun(status) {
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
//////////////////////////
if (status == "ok") {
resolve(); // 성공
} else {
reject(); // 실패
}
//////////////////////////
console.log("2");
});
}
var result = fun("ok");
// resolve 호출에 대한 처리작업: then() 사용.
// reject 호출에 대한 처리작업: catch() 사용.
// 중요: resolve 호출시 즉시 then 호출안되고, 실행될 수 있는 상황에 비동기로 실행됨.
result.then(function () {
console.log("success");
}) // resolve 호출시 실행.
.catch(function () {
console.log("fail");
}) // reject 호출시 실행
.finally(function () {
console.log("finally");
}); // 무조건 실행.
console.log("result: ", result);
console.log("end.");
// 실행결과
// 1
// 2
// result:
// ▶Promise{...}
// end
// success
// finally
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise2_메서드호출2_처리구현2_체인</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
function fun(status) {
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
if (status == "ok") {
resolve(100); // 성공
// 값도 넣을수 있음
// 1. 임의의 서버와 연동해서 문자열 JSON 을 받음.
// ex) "{age:20}"
} else {
reject(); // 실패
}
console.log("2");
});
}
var result = fun("ok");
result.then(function (n) {
// resolve 의 값 -> n
// 2. 문자열 JSON ==> JSON
// ex) return JSON.parse()
console.log("success", n);
return n + 100;
}) // resolve 호출시 실행.
.then(function (m) {
// return n + 100 -> m
// 3. {age:20} 에서 age 이용해서 20을 얻음.
console.log("success2", m);
})
.catch(function () {
console.log("fail");
}) // reject 호출시 실행
.finally(function () {
console.log("finally");
}); // 무조건 실행.
console.log("result: ", result);
console.log("end.");
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise2_메서드호출2_처리구현2_체인2_활용</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
function fun(status) {
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
if (status == "ok") {
// 서버연동했다고 가정
// 1. 임의의 서버와 연동해서 문자열 JSON 을 받음.
// ex) "{age:20}"
var result = '{"age":20}';
resolve(result);
} else {
reject(); // 실패
}
console.log("2");
});
}
var result = fun("ok");
result.then(function (n) {
// resolve 의 값 -> n
// 2. 문자열 JSON ==> JSON
// ex) return JSON.parse()
console.log("result:", n); // {"age":20} 리턴
return JSON.parse(n);
}) // resolve 호출시 실행.
.then(function (m) {
// 3. {age:20} 에서 age 이용해서 20을 얻음.
console.log("result:", m.age); // success2 20
})
.catch(function () {
console.log("fail");
}) // reject 호출시 실행
.finally(function () {
console.log("finally");
}); // 무조건 실행.
console.log("result: ", result);
console.log("end.");
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기1_Promise2_메서드호출2_처리구현2_체인3_arrow함수</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
function fun(status) {
// resolve: 성공시 호출, reject: 실패시 호출
return new Promise(function (resolve, reject) {
console.log("1");
if (status == "ok") {
// 서버연동했다고 가정
// 1. 임의의 서버와 연동해서 문자열 JSON 을 받음.
// ex) "{age:20}"
var result = '{"age":20}';
resolve(result);
} else {
reject(); // 실패
}
console.log("2");
});
}
var result = fun("ok");
// arrow
// 다음과 같은 형식이 사용빈도가 높음.
result.then((n) => JSON.parse(n)) // resolve 호출시 실행.
.then(m => console.log("success2", m.age))
.catch(() => console.log("fail")) // reject 호출시 실행
.finally(() => console.log("finally")); // 무조건 실행.
console.log("result: ", result);
console.log("end.");
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기2_async함수</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// async 키워드로 비동기 함수 생성
// 1. 일반 함수
function fun() {
return "일반함수";
}
// 2. 비동기 함수
async function aSyncfun() {
return "비동기함수"; // 이전 방식의 resolve("비동기 함수");
// 예외발생 발생되었다면 이전 방식의 reject(); 동일
}
// 일반함수 호출
var result = fun();
// 비동기함수 호출
var result2 = aSyncfun();
// 출력
console.log("일반함수: ", result); // "일반함수"
console.log("비동기함수: ", result2); // Promise 객체 반환
// 비동기 함수 aSyncfun() 리턴값 얻기
result2.then(n => console.log(n))
.catch(() => console.log("catch"))
.finally(() => console.log("finally"))
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js16_비동기2_async함수2_await</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// async 와 await 사용
// async 기능: 함수를 비동기함수로 만듬.
// await: async 함수내의 처리를 wait 시킴.
// await 로 지정된 함수가 끝날때 까지.
var result;
async function asyncFun() {
console.log("1");
// result = (function () { console.log("await 함수"); return 100; })();
result = await (function () { console.log("await 함수"); return 100; })();
console.log("END.");
console.log("내부에서 result: ", result);
// return 값; .then() 으로 얻는다.
}
var promise = asyncFun();
console.log("외부에서 result: ", result);
/*
- await 지정하지 않은 경우 실행 결과
1
await 함수
END.
내부에서 result: 100
외부에서 result: 100
- await 지정한 경우 실행 결과
1
await 함수
외부에서 result: ", undefined
END.
내부에서 result: 100
*/
</script>
</head>
<body>
</body>
</html>
###########################################################################
###########################################################################
12장. Ajax
###########################################################################
1. AJAX(Asynchronous Javascript And Xml)
- 비동기 + 자바스크립트 + xml(데이터포맷의미, 현재는 JSON)
==> 클라이언트에서 JS 이용해서 서버와 비동기로 데이터 통신(JSON) 을 하는 방식.
2. 서버와 통신하는 2가지 방법
1> 비 Ajax
요청: a태그, 새로고침, 명시적인 url입력후 엔터, form의 submit
웹브라우저 -----------------> 서버
<----------------
응답: html
- 응답을 html로 받으면 웹 브라우저의 전체 화면이 리로딩 됨.
- 1M 가 되는 전체 html을 서버에서 받아야된다. (네트워크 부하가 심하다.)
- 전체 html 을 받기 때문에 깜박임이 있음. 사용자 UI/UX 가 매우 불편하다.
2> Ajax
요청: JS 이용(XMLHttpRequest 객체)
웹브라우저 -----------------> 서버 (reqres.in 사이트)
<----------------
응답: JSON
ex> {mesg:"logout"}
- 응답을 JSON으로 받으면 웹 브라우저의 전체 화면이 리로딩 안됨. (깜박거림이 없음.)
- 크기가 매우 작은 JSON 데이터를 받는다. (네트워크 부하가 거의 없다.)
- 전체 html 을 받지 않기 때문에 깜박임이 없음. 사용자 UI/UX 가 매우 편하다.
- React 같은 Front-end 프레임워크는 내부적으로 Ajax 로 서버와 연동한다.
3> Ajax 구현
가. 명시적인 XMLHttpRequest 이용 (OLD 방법, 사용안함)
- https://reqres.in/api/users/2
나. async + await + fetch() 이용
- https://reqres.in/api/users/2
<!DOCTYPE html>
<html lang="en">
<head>
<title>js17_Ajax1_async_await_fetch</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
var url = "https://reqres.in/api/users/2";
var req = async function () {
var response = await fetch(url);
console.log(response);
console.log(response.ok);
console.log(response.status);
console.log(response.url);
// 명시적으로 성공/실패 체크해야된다.
if (response.status != 200) {
// 예외처리 코드
} else {
// 성공했을때 실행 코드
// 하단의 코드가 성공코드니 else{} 에 넣으면 된다.
}
var json = await response.json();
console.log(json);
var person = json.data;
console.log(person);
var id = person.id;
var email = person.email;
var first_name = person.first_name;
var last_name = person.last_name;
var avatar = person.avatar;
var table = `
<table border="1">
<tr>
<th>아이디</th>
<th>이메일</th>
<th>이름</th>
<th>아바타</th>
</tr>
<tr>
<td>${id}</td>
<td>${email}</td>
<td>${first_name}</td>
<td><img src='${avatar}' width="100" height="100"></td>
</tr>
</table>
`;
document.querySelector("#result").innerHTML = table;
};
</script>
</head>
<body>
<button onclick="req()">요청</button>
<div id="result"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js17_Ajax1_async_await_fetch2_then_catch함수</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
var url = "https://reqres.in/api/users/2";
var req = async function () {
await fetch(url) // Response 객체
.then(function (response) { return response.json() })
.then(function (json) {
var person = json.data;
console.log(person);
var id = person.id;
var email = person.email;
var first_name = person.first_name;
var last_name = person.last_name;
var avatar = person.avatar;
var table = `
<table border="1">
<tr>
<th>아이디</th>
<th>이메일</th>
<th>이름</th>
<th>아바타</th>
</tr>
<tr>
<td>${id}</td>
<td>${email}</td>
<td>${first_name}</td>
<td><img src='${avatar}' width="100" height="100"></td>
</tr>
</table>
`;
document.querySelector("#result").innerHTML = table;
})
.catch(function () {
console.log("error 발생");
})
.finally(function () {
console.log("finally 발생");
});
};
</script>
</head>
<body>
<button onclick="req()">요청</button>
<div id="result"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>js17_Ajax1_XMLHttpRequest객체</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// XMLHttpRequest 객체 이용
var httpRequest;
// 요청처리 기능하는 함수
function req() {
httpRequest = new XMLHttpRequest();
// 서버에서 응답할 때 처리하는 이벤트 지정
httpRequest.onreadystatechange = res; // 콜백처리. res 함수명만 지정.
httpRequest.open("get", "https://reqres.in/api/users/2", true); // true: 비동기
httpRequest.send(null);
}
// 응답처리 기능하는 함수: reqres.in 에서 반환하는 JSON 처리.
function res() {
// 성공했을 경우
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
// 서버에서 응답한 데이터 얻기
var result = httpRequest.responseText; // String 으로 반환됨.
console.log(result); // 문자열
// JSON 객체로 변경
var json = JSON.parse(result);
console.log(json); // json 객체
var person = json.data;
console.log(person);
var id = person.id;
var email = person.email;
var first_name = person.first_name;
var last_name = person.last_name;
var avatar = person.avatar;
var table = `
<table border="1">
<tr>
<th>아이디</th>
<th>이메일</th>
<th>이름</th>
<th>아바타</th>
</tr>
<tr>
<td>${id}</td>
<td>${email}</td>
<td>${first_name}</td>
<td><img src='${avatar}' width="100" height="100"></td>
</tr>
</table>
`;
document.querySelector("#result").innerHTML = table;
}
}
</script>
</head>
<body>
<button onclick="req()">요청</button>
<div id="result"></div>
</body>
</html>
#####################################
React.js에서 매우 많이 사용되는 코드 패턴
1. arrow 함수
2. 객체분해할당(특히 JSON )
3. async, await 이용한 비동기처리
==> 서버와 연동시 필수
4. fetch() 함수
==> 서버에 요청하는 함수
==> 일반적으로 async, await와 같이 사용.
5. 백티 사용
6. 모듈
- import 및 export
7. Array객체 메서드
- map함수
- filter함수
- foreach함수
'[study]이론정리 > HTML & CSS & JavaScript' 카테고리의 다른 글
jQuery 1일차 - 설치, ready, DOM(this), selectors, 2차필터링 (0) | 2024.05.16 |
---|---|
js 이론정리 (0) | 2024.05.16 |
js 6일차 - 클래스, 모듈 (0) | 2024.05.16 |
js 5일차 - DOM(DOM, 객체분해할당) (0) | 2024.05.09 |
js 5일차 - event(2) preventDefault (0) | 2024.05.09 |