부트캠프/[POSCO x Codingon] 웹개발자 풀스택 과정 12기

[POSCO x Codingon] node.js - callback, promise, form, dynamic form | 웹개발자 풀스택 과정 12기 6주차 회고 2

hyunh404 2024. 3. 31. 21:56
728x90

 

 

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 함수로 정의된 코드 (출처-코딩온)

 

 

위와 같이 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();

 

 

 

 

 

728x90

 


 

 

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}입니다.`
                }
            })
        }
</script>

 

 

2️⃣ axios

 

: promise api를 활용한다. return이 promise 객체로 온다.

: 브라우저 호환성이 뛰어나다.

: 단점은 모듈을 설치하거나 호출을 해야만 사용이 가능하다.

 

<script>
        //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}입니다.`
                }
            })
        }
</script>

 

 

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을 전송하는 방법을 배우고 연습하는 과정이 가장 재미있었다.
코드를 직접 작성하며 구조를 이해해갈 수 있어서 좋았고, 방법에 따라 전송되는 과정이 다름을 배워가는 것도 재미있었다.

현재 동적 폼을 전송하는 방법에 대해서도 배웠고, 실습도 해보고 있지만, 구조를 이해하려면 연습이 좀 더 필요할 것 같다.
과제로 주어진 실습을 해보면서 과정을 좀 더 이해해보려고 한다.
728x90