Node

[Node.js] 동기와 비동기 통신 방법에 대하여 알아보기

YaluStar 2023. 3. 4. 01:07

안녕하세요.

이번에는 동기와 비동기 통신 방법에 대하여 알아보겠습니다.

 

1. 동기와 비동기 통신

1-1. 동기 방식

  • 한 번에 하나만 처리 => 페이지를 아예 이동해 서버가 데이터 처리

 

1-2. 비동기 방식

  • 서버에 데이터를 보내고 응답을 기다리는 동안 페이지 이동 없이 처리하는 방식

 

1-3. 비동기 HTTP 통신

  • 웹 문서가 정적으로 멈춰있는 것이 아니라 일부 내용이 실시간으로 변경되는 것
  • 폼의 데이터를 서버와 dynamic 하게 송수신하는 것

 

2. 비동기 HTTP 통신 방법

2-1. Ajax

  • 자바스크립트를 이용해 클라이언트와 서버 간에 데이터를 주고받는 비동기 HTTP 통신

장점

  • JQuery를 통해 쉽게 구현 가능
  • Error, Success, Complete의 상태를 통해 실행 흐름을 조절할 수 있다.

단점

  • JQuery를 사용해야만 간편하고 환성이 보장된다
  • Promise 기반이 아니다.

 

2-2. Axios

  • Node.js와 브라우저를 위한 Promise API를 활용
  • 비동기 HTTP 통신이 가능, return이 Promise 객체로 온다.

장점

  • Timeout 기능이 존재한다.
  • Promise 기반으로 만들어졌다.
  • 브라우저 호환성이 뛰어나다.

단점

  • 모듈 설치나 CDN을 해줘야 사용이 가능하다.

 

2-3. Fetch

  • ES6부터 들어온 JavaScript 내장 라이브러리
  • Promise 기반

장점

  • JavaScript 내장 라이브러리이므로 별도의 import 필요 X
  • Promise기반

단점

  • 최신 문법 - 호환 문제가 생길 수 있다.
  • Timeout 기능이 없다. => 대기 시간이 무한 정이다.
  • 상대적으로 Axios에 비해 기능 부족

 

3. Axios 문법 - Post

  • url: 서버 주소, form에서의 action에 해당한다.
  • method: 요청 방식 (get, post, patch, delete 등)
  • data: 보내려는 데이터
    • { key: value, key: value }
    • 위와 같은 형태로 만들어 보낸다.
    • put, post, patch 일 때 사용
    • Request의 body로 데이터를 보낸다.
axios({
	url: '주소',
	method: '방식',
	data: { json 형태의 데이터 }
});

 

3-1. Axios 문법 - Get

- Get 방식으로 보내는 경우 작성 data 대신 params로 데이터를 전달한다.

axios({
	url: '주소',
	method: 'get',
	params: { json 형태의 데이터 }
});

 

3-2. Axios 문법 - 응답

- 서버에서 요청 이후 받은 응답 값을 then() 함수에서 확인할 수 있다.

axios({
	url: '주소',
	method: '방식',
	data: { json 형태의 데이터 }
})
.then((response) => {
	console.log(response.data);
	console.log(response.status);
});

 

 

4. Ajax 문법

  • Get, Post 양식 동일하며, type 부분에서 method만 변경해서 사용해 주면 된다.
$.ajax({
    url: '/login',
    type: 'post',
    data: {
        id: form.id.value,
        pw: form.pw.value
    },
    success: function(data) {
        console.log(data);
    },
    error: function(error) {
        console.log(error);
    }
});

 

 

5. Fetch 문법

  • Post와 Get의 양식이 다르며, Post 방식으로 사용하는 경우 추가적으로 입력을 해야 하는 값이 존재한다.

- Fetch Post 방식

fetch('/login', {
    method: 'post',
    headers: {
        "Content-Type": "application/json",
    },
    body: JSON.stringify({
        id : form.id.value,
        pw : form.pw.value
    })
})
.then((response) => response.json())
.then((data) => {
    console.log(data);
});

 

- Fetch Get 방식

fetch('/login'+urlQuery, {
    method: 'get',
})
.then((response) => response.json())
.then((data) => {
    console.log(data);
});

 

 

데이터를 보낼 때 JSON 형식으로 보내는데, JSON이 무엇인지 모르시는 분들을 위하여 아래 추가 내용으로 작성합니다.

6. JSON

  • "키-값 쌍"으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다.
  • 비동기 브라우저/서버 통신을 위해 사용하는 데이터 포맷이다.

Ex)

{
  "이름": "홍길동",
  "나이": 55,
  "성별": "남",
  "주소": "서울특별시 양천구 목동",
  "특기": ["검술", "코딩"],
  "가족관계": {"#": 2, "아버지": "홍판서", "어머니": "춘섬"},
  "회사": "경기 수원시 팔달구 우만동"
}

 

 

실습코드

더보기
  1. Axios 실습

axios를 이용하여 데이터 받는 작업하기

 

index.ejs

<!DOCTYPE html>
<html lang="en, ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Axios 비동기 방식</title>
    <!-- Axios CDN -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        function sendGet() {
            let form = document.getElementById('form_info');
            // form.name.value
            // form 태그 안에서 name을 가진 input의 값을 가져오겠다.
            // form 태그에서만 사용 가능한 방법

            // axios get을 이용한 통신
            axios({
                method: "get",
                url: "/form",
                params: {
                    // name: "codingOn"
                    name: form.name.value
                }
            })
            .then(function(res) {
                console.log(res);
                // 방법 1
                alert(res.data);
                // 방법 2
                // alert(res.data.msg);
            });
        }

    </script>
</head>
<body>
    <div>
        <button type="button" onclick="sendGet();">get 전송</button>
    </div>
    
    <form id='form_info' action="/form" method="post">
        이름 : <input tpye="text" name="name">
    </form>
</body>
</html>

 

index.js

const express = require('express');
const app = express();
const port = 8080;

app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: true}));
app.use(express.json());

app.get('/', (req, res) => {
    res.render('index');
});

app.get('/form', function(req, res) {
    console.log(req.query);
    // 방법1
    res.send('이름은 : ' + req.query.name);
    // 방법2
    // res.send({msg: ' 이름은 : ' + req.query.name});
});

app.listen(port, () => {
    console.log('server open : ', port);
});

 

실행 결과 - html

 

실행 결과창

 

 

 

사용은 방법 1, 방법 2 2가지 방식이 있는데

방법 1의 경우에는 바로 메시지를 전달해 주는 방식이고,

방법 2의 경우에는 msg라는 변수에다가 출력할 메시지를 저장한 후에 다시 index.ejs 파일에다가 전달해 줘서 출력하는 방식입니다.

실습코드 2

더보기

Axios 실습 2

폼에서 데이터 넘겨줘서 alert 창으로 출력하기

 

index2.ejs

<!DOCTYPE html>
<html lang="en, ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Axios 실습</title>
    <!-- Axios CDN -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    
    <script>
        function sendGet() {
            let form = document.getElementById('form_info');
            axios({
                method: "get",
                url: "/form",
                params: {
                    name: form.name.value,
                    gender: form.gender.value,
                    birth: form.birthYear.value + '년 ' + form.birthMonth.value + '월 ' + form.birthDate.value + '일',
                    interest: form.interest.value,
                    birth2: [form.birthYear.value, form.birthMonth.value, form.birthDate.value]
                    // list 방식으로 넘겨줄 수 도 있음
                }
            })
            .then(function(res) {
                console.log(res.data);
                alert('이름은 ' + res.data.name + ' / 성별은 ' + res.data.gender + ' / 생일은 ' + res.data.birth);
            });
        }

    </script>
</head>
<body>
    <form action="/form" method="get" id="form_info">
        <label for="name">이름</label><input type="text" id="name" name="name" autofocus required>
        <fieldset>
            <legend>성별</legend>
            <input type="radio" id="man" name="gender" value="남자"><label for="man">남자</label>
            <input type="radio" id="woman" name="gender" value="여자"><label for="woman">여자</label>
        </fieldset>

        <fieldset>
            <legend>생년월일</legend>
            <select name="birthYear">
                <% for (let i = 2010; i <= 2022; i++) { %>
                <option value="<%= i %>"><%= i %></option>
                <% } %>
            </select>
            <span>년</span>
            <select name="birthMonth">
                <% for (i = 1; i <= 12; i++) { %>
                <option value="<%= i %>"><%= i %></option>
                <% } %>
            </select>
            <span>월</span>
            <select name="birthDate">
                <% for (i = 1; i<= 31; i++) { %>
                <option value="<%= i %>"><%= i %></option>
                <% } %>
            </select>
            <span>일</span>
        </fieldset>

        <fieldset>
            <legend>관심사</legend>
            <input type="checkbox" name="interest" id="interestTravel" value="여행"><label for="interestTravel">여행</label>
            <input type="checkbox" name="interest" id="interestfff" value="패션"><label for="interestfff">패션</label>
            <input type="checkbox" name="interest" id="interestFood" value="음식"><label for="interestFood">음식</label>
        </fieldset>
        
        <br>
        <button type="button" onclick="sendGet()">회원가입</button>
    </form>
</body>
</html>

 

index.js

const express = require('express');
const app = express();
const port = 8080;

app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: true}));
app.use(express.json());

app.get('/', (req, res) => {
    res.render('index2');
});

app.get('/form', (req, res) => {
    console.log(req.query);
    res.send(req.query);
});

app.listen(port, function() {
    console.log('server open : ', port);
});

 

실행 결과 - html

실행 결과 - 콘솔 창

실습코드 3

더보기

Axios 실습 3

 

index4.ejs

<!DOCTYPE html>
<html lang="en, ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Axios 비동기 방식</title>
    <!-- Axios CDN -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

    <script>
        function login() {
            let form = document.getElementById('form_info');
            let loginMsg = document.getElementById('loginMsg');
            axios({
                method: "post",
                url: "/login",
                data: {
                    id : form.id.value,
                    pw : form.pw.value
                }
            })
            .then(function(res) {
                console.log(res);
                // alert(res.data.msg);
                loginMsg.innerHTML = res.data.msg;
            });
        }

         
    </script>
</head>
<body>
    <div>
        <form id='form_info' action="/login" method="post">
            아이디 : <input tpye="text" name="id">
            비밀번호 : <input tpye="text" name="pw">
            <br>
            <button type="button" onclick="login();">로그인</button>
        </form>
        <div id='loginMsg'></div>
    </div>
</body>
</html>

 

index4.js

const express = require('express');
const app = express();
const port = 8080;

app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: true}));
app.use(express.json());

app.get('/', (req, res) => {
    res.render('index4');
});

app.post('/login', function(req, res) {
    console.log(req.body);
    if(req.body.id == 'admin' && req.body.pw == '1234') {
        console.log('로그인 성공');
        res.send({msg: '<p style="color: blue;">로그인 성공</p>'});
        // res.send('로그인 성공');
    } else {
        console.log('로그인 실패');
        res.send({msg: '<p style="color: red;">로그인 실패</p>'});
        // res.send('로그인 실패');
    }
});

app.listen(port, () => {
    console.log('server open : ', port);
});

 

실행 결과 - html

실행 결과 - 콘솔 창

 

이상으로 Node.js의 비동기 통신 방법인 ajax, axios, fetch에 대하여 알아보았습니다.

감사합니다.

반응형