-
[멋쟁이사자처럼] json-server 이용한 JS비동기 통신 특강Front-end 개발 2023. 9. 27. 22:04
목차
1. 비동기
2. json-server 만들기
3. Fetch API 를 이용해 서버와 데이터 통신하기
오늘은 비동기 개념을 보충해주는 특강이 있다.
즐거운 한가위를 맞이하기 전 마지막 수업으로 찝찝했던 부분을 일부 해소할 수 있었다.
이전까지는 간단한 database 없이, html 에 바로 생성하거나 브라우저 로컬스토리지를 이용 todo 리스트를 만들어 보았다. 이번 수업에서는 간단한 json 서버를 만들고 데이터를 생성하고, 읽어오고, 제거해 본다.
추석 연휴 전날까지 고생해주신 강사님께 감사할 따름이다.
1. 비동기
1-1. 동기적인 처리
- 비동기 처리는 동기적으로 처리되지 않는 것을 이야기한다.
-하나의 흐름에서 순차적
- 출력1 > 출력2 > 출력3
- 각각의 함수는 완전히 종료되며 이어진다.
const 출력1 = ()=>console.log(1) const 출력2 = ()=>console.log(2) const 출력3 = ()=>console.log(3) 출력1() 출력2() 출력3() // 출력 // 1 // 2 // 3
- 하지만 비동기는 그렇지 않다.
1-2. 비동기적인 처리
const 출력1 = ()=>console.log(1) const 출력2 = ()=>console.log(2) const 출력3 = ()=>console.log(3) // 비동기 const 비동기출력1 = ()=>{ console.log("비동기함수1실행") setTimeout(출력1,1000); } const 비동기출력2 = ()=>{ console.log("비동기함수2실행") setTimeout(출력2,1500); } const 비동기출력3 = ()=>{ console.log("비동기함수3실행") setTimeout(출력3,500); } 비동기출력1() 비동기출력2() 비동기출력3() // 출력 // 비동기함수1실행 // 비동기함수2실행 // 비동기함수3실행 // undefined // 3 // 1 // 2
- 실행이 하나의 흐름에 존재하지 않기 때문에 위와 같은 현상이 일어난다.
- 출력3 > 출력1 > 출력2
- 실행은 순차적으로 진행되지만 각각의 함수 실행은 개별적으로 진행된다.
- 다른 작업의 종료와 상관없이 영향을 받지 않고 실행된다.
- JS 는 동기적으로 동작하지만, 비동기를 지원한다.
1-3. 비동기 통신
- 왜 통신을 하는데 비동기라는 용어를 붙여 놓았을까?
- 각 작업은 별도로 행동하는 주체이며 비동기적으로 행동한다고 본다.
- 구글 맵이 페이지 이동할 때 멈추거나, 인스타그램이 댓글을 써서 멈춘다면 정말 불편할 것이다.
- AJAX 라는 기법은 비동기 자바스크립트 그리고 XML 의 줄임말이다.
1-4. Fetch API 기초 사용법
- 총 2가지 방법을 이용해 본다.
- fetch는 HTTP 통신을 이용한다.
- fetch(<url>) : fetch를 이용해 get 요청을 보내게 된다.
- fetch(url, [option] : fetch에 URI 뿐만 아닌 다른 속성을 객체형태로 념겨주어 요청을 보낸다.
- get 은 데이터를 받아오는 것이다.
- post 는 데이터를 보내는 것이다.
- fetch 에서는 HTTP는 body에 들어가 있다.
//fetch로 get요청 보내기, 옵션을 넣지 않으면 get요청이다. fetch("요청할주소") //fetch에 옵션을 넣어 POST요청 보내기 fetch("요청할 주소",{ method: "POST", header: { "Content-Type":"application/json" }, body: "{text:'안녕하세요'}" })
- 책추천: HTTP 완벽 가이드
- 최소한 1 ~ 3장까지 읽을 것
2. json-server 만들기
2-1. json-server 를 이용해 간단한 서버 만들어보기
- 서버를 만들기 위해 json-server 를 npm 으로 설치해보자
npm install -g json-server
- fetch 폴더 > db 폴더 > db.json 파일 생성
{ "todos":[] }
- json-server 실행
json-server --watch db.json // 실행 후 브라우저 접속 http://localhost:3000/todos
- URI 를 통해 들어간 형태가 get 요청이다.
3. fetch 를 이용해 서버와 서버와 통신하기
- 브라우저 about:blank 에 접속해서 개발자 도구를 열어보자
- 개발자 도구 콘솔에서 fetch 를 이용해 get 요청을 해본다.
fetch('http://localhost:3000/todos').then(res=>res.json()).then(json=>console.log(json))
- db.json 파일의 데이터를 바꿔본다.
{ "todos":[{ "id":1, "todo":"밥먹기" }] }
- 갱신된 데이터를 fetch 로 불러와 확인해보자
2-3. html 파일에서 fetch 이용해서 서버와 통신하기
- json-server 를 켜둔 상태로 vscode 에서 파일을 생성한다.
- db.json 파일과 다른 폴더 경로에 새로운 폴더와 index.html 파일을 생성한다.
- 그 이유는 json-server 에 데이터 요청으로 변경이 되면 새로고침을 수행한다.
이때 index.html 이 같은 경로에 있다면, fetch 를 실행하는 index.html도 재실행되기 때문이다.- fetch 폴더 > HTML 폴더 > index.html 경로에 생성한다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> fetch("http://localhost:3000/todos") .then(data=>data.json()) .then(json=>console.log(json)) </script> </body> </html>
- 현재 vscode live 서버는 5500 port로 열려있고, json-server 는 3000 port에 열려 있는 상황이다.
- live 서버에서는 데이터를 json-server 에서 데이터를 가져가고 있다.
2-4. fetch 에서 Post 를 이용하기
- 데이터를 보내거나, 로그인을 할 때 post 를 사용한다.
- post 요청을 하면서 필요한 명세를 적어서 보낸다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> fetch("http://localhost:3000/todos",{ method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify({ todo:"밥안먹기" }), }) .then(data=>data.json()) .then(json=>console.log(json)) </script> </body> </html>
- post 요청을 보내서 json-server 데이터가 추가되었다.
2-4. button 으로 데이터 추가하기
- createTodo 와 getTodoList 를 정의하여 데이터를 추가하고 읽어온다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>todo 추가</button> <div id="todo"></div> <script> const $button = document.querySelector("button"); const createTodo = () => { fetch("http://localhost:3000/todos", { method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify({ todo: "밥안먹기" }), }) .then(data => data.json()) .then(json => { console.log(json) getTodoList() }) } const getTodoList = () => { fetch("http://localhost:3000/todos") .then(data => data.json()) .then(json => { document.querySelector("#todo").innerHTML = "" json.forEach(todo => { document.querySelector("#todo") .innerHTML += `<li>${JSON.stringify(todo)}</li>` }) }) } $button.addEventListener("click", createTodo) getTodoList(); </script> </body> </html>
2-5. input 요소로 text 를 받아 서버로 데이터 보내기
- input 요소의 value 를 가져와 event 핸들러에 적용시키기
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input /> <button>todo추가</button> <div id="todo"></div> <script> const $button = document.querySelector("button"); // 텍스트를 입력받아서 서버로 요청을보내는 함수! const createTodo = (todoText) => { fetch("http://localhost:3000/todos", { method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify({ todo: todoText }), }) .then(data => data.json()) .then(json => { console.log(json) getTodoList() }) } const getTodoList = () => { fetch("http://localhost:3000/todos") .then(data => data.json()) .then(json => { document.querySelector("#todo").innerHTML = "" json.forEach(todo => { document.querySelector("#todo") .innerHTML += `<li>${JSON.stringify(todo)}</li>` }); }) } const inputTodo = () => { // 인풋요소에서 값을 가져온다. const todoText = document.querySelector("input").value // 가져온 값을 createTodo에 넘겨준다! createTodo(todoText) document.querySelector("#todo").innerHTML = "" } $button.addEventListener("click", inputTodo); getTodoList(); </script> </body> </html>
2-6. delete 로 db 데이터 제거하기
- HTTP 메소드 delete 를 활용하기
- id 는 getTodoList 의 todo 에 들어 있다.
- innerHTML 로 요소를 붙이면 event 가 지워진다.
- li 요소를 append 로 붙인다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input /> <button>todo추가</button> <div id="todo"></div> <script> const $button = document.querySelector("button"); // 텍스트를 입력받아서 서버로 요청을보내는 함수! const createTodo = (todoText) => { fetch("http://localhost:3000/todos", { method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify({ todo: todoText }), }) .then(data => data.json()) .then(json => { console.log(json) getTodoList() }) } const getTodoList = () => { fetch("http://localhost:3000/todos") .then(data => data.json()) .then(json => { document.querySelector("#todo").innerHTML = "" json.forEach(todo => { const $li = document.createElement("li") $li.innerHTML = todo.todo; const $deleteButton = document.createElement("button"); $deleteButton.addEventListener("click", () => deleteTodo(todo.id)); $deleteButton.innerText = todo.id + "삭제"; document.querySelector("#todo").append($li, $deleteButton) }); }) } const inputTodo = () => { // 인풋요소에서 값을 가져온다. const todoText = document.querySelector("input").value // 가져온 값을 createTodo에 넘겨준다! createTodo(todoText) document.querySelector("#todo").innerHTML = "" } const deleteTodo = (id) => { fetch("http://localhost:3000/todos/" + id, { method: "DELETE" }) .then(data => data.json()) .then(json => { getTodoList() }) } $button.addEventListener("click", inputTodo); getTodoList(); </script> </body> </html>
'Front-end 개발' 카테고리의 다른 글
[책집필] 면접 질문 - DNS (0) 2023.10.14 [책집필] 자바스크립트 엔진 V8 코드 해석 과정 (0) 2023.10.02 [책집필] REST API (0) 2023.09.27 [책집필] 기술면접 질문 - CORS, Proxy (0) 2023.09.24 [원티드] 프리온보딩 9월 챌린지 - 반응형 웹 사이트 개발 3일차 (0) 2023.09.13