6주차 회고
이어서 node.js의 모듈인 express, ejs 등과 form을 활용해 데이터를 전송하는 연습을 해볼 수 있었다.
또한, 비동기 처리, 콜백 함수, promise, async - await 문법도 배우고 실습해볼 수 있었다.
1. callback 함수
: 비동기 코드를 처리하기 위한 방법 1
: 다른 함수가 실행을 끝낸 뒤 실행되는 함수이다. => 매개변수로 함수를 받아서 사용할 수 있다.
=> 콜백함수를 사용하는 이유는 응답을 받은 후 처리돼야하는 작업이 있을 수 있으므로, 함수가 다른 함수의 실행을 끝낸 뒤 실행되는 것을 보장하기 위해서라고 한다..!!
아래의 코드는 가장 기본적인 형태의 콜백함수이다.
=> 함수를 먼저 선언한 후 맨 마지막에 함수를 하나 더 선언하는 방식으로 정의한다.
getUser(1, function(user){
console.log('User', user)
})
function getUser(id,abc){
setTimeout(()=>{
console.log('Reading data...');
abc({id:id, gitHubUsername:'hong'})
}, 2000)
}
그러나, 콜백함수는 가독성이 떨어지며 코드 수정 난이도가 높아진다는 단점이 존재한다.
2. promise
: 비동기 코드를 처리하기 위한 방법 2
: 미래의 완료, 실패와 결과값을 나타낸다. => 성공(then)과 실패(catch)를 분리해 반환한다.
: 다음 작업을 연결시켜 진행할 수 있다.
기본적인 promise의 형태이다. 함수를 정의하고, 실행이 성공(res)하면 then의 결과를 반환하고, 실패(rej)하면 catch의 결과값을 반환한다.
const p = new Promise((res,rej)=>{
setTimeout(()=>{
rej(new Error('오마이갓'))
}, 2000)
})
p
.then(result=>console.log('2초 후의 결과는', result))
.catch(err=>console.log('에러 발생', err.message))
3. async - await
: 비동기 코드를 처리하기 위한 방법 3
: promise도 체이닝을 하게되면 코드의 가독성이 떨어질 수 있다. 보다 직관적인 코드를 위한 방법이다.
: async - 비동기 실행되는 것이 있음을 알린다. / await - 실행이 다 될 때까지 기다리게한다. => 반드시 둘은 같이 써야한다.
새로운 방법이 추가된 것이 아닌 promise를 다르게 사용하는 것이다.
아래의 코드가 기본적인 형태이다.
async function exec(){
const name = await callPromise('Kim');
console.log(`${name} 반가워`)
const txt = await backPromise();
console.log(`${txt}을 실행했군요`)
const msg = await hellPromise();
console.log(msg)
}
exec();
배운 것을 활용해 callback 함수를 promise 함수로 바꾸고, async - await을 사용해보는 실습을 해볼 수 있었다.
위와 같이 callback으로 함수가 주어졌고, 같은 결과값이 나오도록 promise 방법으로 바꿔야했다.
아직 promise의 구조를 다 이해하지 못해서 promise 함수를 어디어 정의해야하고 async - await에 정의할 내용도 무엇이 들어가야하는지 헷갈리기도 했다.
그러나,
직접 코드를 작성하고 결과값을 확인하며 코드를 수정해가면서 promise의 구조를 확인할 수 있었다.
결과적으로, 기대 결과값을 출력해낼 수 있었다.
구조를 이해해가는 과정이 재미있었다. 실습하면서 작성한 코드도 올려두겠다.
function call(name, cb){
return new Promise((res,rej)=>{
setTimeout(()=>{
console.log(name)
res({name:name, cb:name})
}, 1000)
})
}
function back(back){
return new Promise((res,rej)=>{
setTimeout(()=>{
console.log('back')
res(['back'])
}, 1000)
})
}
function hell(hell){
return new Promise((res,rej)=>{
setTimeout(()=>{
console.log('callback hell')
res(['callback hell'])
}, 1000)
})
}
async function callBack_Promise(){
try{
const call1 = await call('Kim');
console.log(`${call1.name} 반가워`)
const back1 = await back(call1.cb);
console.log(`${back1}을 실행했구나`)
const hell1 = await hell(back1);
console.log(`여기는 ${hell1}`)
} catch(err){ //실행되다 오류나면 catch문으로 오도록
console.log('Error', err.message)
}
}
callBack_Promise();
4. form 전송
: method - 전송 방법 결정
- GET : url에 form 내용이 보여진다.
- POST : url에 form 내용이 보이지 않는다.
자바스크립트에서도 url을 불러올 때 method에 따라 app.get / app.post로 명령어가 변경된다.
이를 활용해서 로그인 데이터를 get, post로 받는 자바스크립트 코드를 작성하는 실습을 해볼 수 있었다.
서버를 구축하는 방법으로 express를 사용했고, ejs 템플릿을 사용하기 위해 views라는 폴더에 ejs 파일을 저장했다.
다음으로 app.use를 사용해 req, body 객체를 해석할 수 있는 body-parser 미들웨어를 정의하고, json 형식으로 데이터를 받기위해 코드를 작성해주었다.
마지막으로 form method에 따라 app.get, app.post를 이용해 파일을 렌더링해주었다.
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.set('views', './views');
app.use(express.urlencoded({extended:true}));
app.use(express.json());
app.get('/', (req,res)=>{
console.log('루트에서 들어옴')
res.render('index')
})
app.get('/login', (req,res)=>{
console.log('로그인 GET 요청')
console.log(req.query)
res.render('result', {title:'GET 로그인 화면', userInfo:req.query})
})
app.post('/login', (req,res)=>{
console.log('로그인 POST 요청')
console.log('req body--->', req.body)
res.render('result', {title:'POST 로그인 화면', userInfo:req.body})
})
app.listen(8080, ()=>{
console.log('Server is running...')
})
5. dynamic(동적) form 전송
1️⃣ ajax
: 클라이언트와 서버간에 XML데이터를 주고 받는 기술
: 웹브라우저가 서버와 비동기적으로 데이터를 교환할 수 있게해주는 api
: 자바스크립트 라이브러리, 전체 페이지 새로고침을 안해도 페이지 일부만 데이터 로드한다.
: key & value로 값을 전달한다.
ajax로 자바스크립트 코드를 작성하는 기본적인 형태이며, method type만 변경하는 것 외에는 구조가 동일하다.
정의해준 url을 사용해 자바스크립트 파일에서 렌더링 시 url을 불러온다.
<script>
//ajax get
function ajaxGet(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
$.ajax({
type: 'get',
url: '/ajax',
data: data,
success: function(data){
console.log('ajax--->',data);
resultBox.textContent = `Get/ajax 요청완료! ${data.name} 님의 성별은 ${data.gender}입니다.`
}
})
}
//ajax post
function ajaxPost(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
$.ajax({
type: 'post',
url: '/ajax',
data: data,
success: function(data){
console.log('ajax--->',data);
resultBox.textContent = `Post/ajax 요청완료! ${data.name} 님의 성별은 ${data.gender}입니다.`
}
})
}
2️⃣ axios
: promise api를 활용한다. return이 promise 객체로 온다.
: 브라우저 호환성이 뛰어나다.
: 단점은 모듈을 설치하거나 호출을 해야만 사용이 가능하다.
//axios get
function axiosGet(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
axios({
method: 'get',
url: '/axios',
params: data
}).then((response)=>{
console.log(response.data);
resultBox.textContent=`Get/axios 요청 성공 ${data.name}님의 성별은 ${data.gender}입니다.`
}).catch((err)=>{
console.log('ERROR');
resultBox.textContent=`Get/axios 요청 실패 ${err.response.data}`
})
}
//ajax post
function ajaxPost(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
$.ajax({
type: 'post',
url: '/ajax',
data: data,
success: function(data){
console.log('ajax--->',data);
resultBox.textContent = `Post/ajax 요청완료! ${data.name} 님의 성별은 ${data.gender}입니다.`
}
})
}
3️⃣ fetch
: promise를 기반으로 하며, 자바스크립트의 내장 라이브러리로 별도의 import가 필요없다.
: 단점은 timeout 기능이 없고 상대적으로 axios에 비해 기능이 부족하다.
fetch는 get, post에 따라 구조가 살짝 다르게 주어진다.
get은 url과 함께 전달할 데이터를 같이 작성해주었다.
post는 headers를 함꼐 정의해주어야 한다.
<script>
//fetch get
function fetchGet(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
fetch(`/fetch?name=${data.name}&gender=${data.gender}`, {
method:'GET'
}).then((response)=>{
return response.json()
}).then(data=>{
console.log('DATA : ', data);
resultBox.textContent=`Get/fetch 요청 완료 ${data.name}님의 성별은 ${data.gender}입니다.`
})
}
//fetch post
function fetchPost(){
const resultBox = document.querySelector('.result');
const form = document.forms['register'];
const data = {
name: form.name.value,
gender: form.gender.value
}
fetch('/fetch', {
method:'POST',
headers: {'Content-Type':'application/json'}, //차이점
body: JSON.stringify(data)
}).then((response)=>{
return response.json()
}).then(data=>{
console.log('DATA : ', data);
resultBox.textContent=`Post/fetch 요청 완료 ${data.name}님의 성별은 ${data.gender}입니다.`
}).catch(err=>{
console.log('ERROR', err,massage);
})
}
</script>
자바스크립트를 배우면서 form을 전송하는 방법을 배우고 연습하는 과정이 가장 재미있었다.
코드를 직접 작성하며 구조를 이해해갈 수 있어서 좋았고, 방법에 따라 전송되는 과정이 다름을 배워가는 것도 재미있었다.
현재 동적 폼을 전송하는 방법에 대해서도 배웠고, 실습도 해보고 있지만, 구조를 이해하려면 연습이 좀 더 필요할 것 같다.
과제로 주어진 실습을 해보면서 과정을 좀 더 이해해보려고 한다.