본문 바로가기
강의/스파르타코딩클럽

[리액트 숙련주차] 2-21~23 비동기 프로그래밍

by gardenii 2023. 7. 11.

2-21 비동기 프로그래밍 입문

1. 동기 방식과 비동기 방식

동기적(synchronous) 방식

- 현재 실행중인 코드가 끝나야 다음 코드를 실행하는 방식

- 일반적 프로그래밍 세계에서 코드는 모두 동기적으로 실행됨

 

비동기적(not synchronous) 방식

- 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어가는 방식

- setTimemout, addEventListner 등

- 별도의 요청, 실행 대기, 보류 등과 관련된 코드는 모두 비동기적 코드

- 대표적으로 서버 통신과 관련된 로직들을 포함함

ex) 중식집에서 배달 후 배달원이 다먹을때까지 기다렸다가 그릇을 회수하지 않고, 다른 집도 갔다가 다시 찾으러 오는 것과 비슷함

2. 콜백지옥

- 콜백함수를 익명함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 너무 높아지는 경우

- 주로 이벤트 처리 및 서버 통신과 같은 비동기적 작업을 수행할 때 발생

- 가독성, 수정이 어려움

 

=> 즉 이를 해결하기 위해 ES6 에서 Promise 객체가 나옴

=> 비동기 프로그래밍 = Promise 다룬다

2. Promise 객체

1. 개념

- 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과값을 나타냄

 

왜 이름이 약속일까?

- 비동기 작업은 수행의 제어권을 제 3자에게 넘겨준 후 작업이 완료되면 안내를 받아 제어권을 이양받는 식의 일처리 방법

- 즉 약속에 따라 제어권을 넘겨주고 넘겨받는 것

- 그 약속에 관련된 사항들이 모두 Promise 객체에 담기게 됨

2. Promise 객체에 담기는 주요한 상태 정보

- 대기(pending) : 요청 직후. 아직 성공 또는 실패되지 않은 상태 

- 이행(fulfilled) : 데이터 전달을 성공적으로 해 준 상태

- 거부(rejected) : 데이터 전달을 못해준 경우

3. Promise 객체 핸들링 방법

- 주요한 상태정보 3가지에 따라 적절한 처리를 해주어야 함

# then ~ catch

// http://api.naver.com/weather/today 로 요청을 한다고 가정합시다.

axios.get('http://api.naver.com/weather/today')
.then(response => {
	console.log('정상처리 되었습니다 : ' + response);
})
.catch(error => {
	console.log('오류가 발생하였습니다 : ' + error);
})
.finally(()=>{
	console.log('항상 실행되는 부분입니다!');
});

axios.get 으로 요청을 보낸 후, 받아온 값이 promise 객체

성공하면 then으로 응답 값 출력

에러가 나오면 catch로 에러 출력

성공 여부와 상관없이 finally로 항상 실행 

# acync ~ await

const getWeather = async () => {
	try {
		const response = await axios.get('http://api.naver.com/weather/today');
		console.log('정상처리 되었습니다 : ' + response);
	} catch (error) {
		console.log('오류가 발생하였습니다 : ' + error);
	}
}

함수 소괄호 앞에 async 붙여줌 -> 비동기함수구나!

중괄호 안에서 await를 만나면 그 구문이 끝날때까지 기다림

 

왜 써야 하는가?

- 코드에서는 일의 순서가 중요, 비동기프로그래밍을 동기적으로 작동해야 하는 경우 있음

2-22 REST (Path Variable, Query Parameter)

1. REST API란?

- REpresentational State Transfer의 약자

- 어떤 자원에 대해 CURD를 진행할 수 있게 HTTP Method(GET, POST, PUT, DELETE)를 사용하여 요청을 보내는 것

- 요청을 위한 자원은 특정한 형태로 표현된다.

- URI를 통해 자원을 표현하고, 자원의 행위를 HTTP Method로 명시한다.

자원(Resource) : URI
행위(Verb) : HTTP Method
표현(Representations)

2. 예시 - 좋은 예시 나쁜 예시

// bad
GET /members/delete/1
// good
DELETE /members/1

// bad
GET /members/show/1
// good
GET /members/1

// bad
GET /members/insert/2
// good
POST /members/2

3. 규칙

http://example.com/posts     (O)
http://example.com/posts/    (X)
http://example.com/post      (X)
http://example.com/get-posts (X)
--> URI는 명사를 사용하고 소문자로 작성되어야 한다.
--> 명사는 복수형을 사용한다.
--> URI의 마지막에는 /를 포함하지 않는다.

http://example.com/post-list  (O)
http://example.com/post_list  (X)
--> URI에는 언더바가 아닌 하이픈을 사용한다.

http://example.com/post/assets/example  (O)
http://example.com/post/assets/example.png  (X)
--> URI에는 파일의 확장자를 표시하지 않는다.

4. RestFul 하다는 것?

- REST API의 조건을 만족시킨 통신 설계 상태를 말함

- 그 누가 보더라도 이해하기 쉽고, 사용하기 쉬운 REST API일 때

5. RestFul 하지 못하다는 것?

- CRUD의 기능을 모두 POST 로만 이용하는 경우

- URI에 행위에 대한 부분이 들어가는 경우 (/classes/createPeople)

6. Path Variable vs Query Parameter

Path Variable

/user/10

- 경로 자체에 변수를 사용한 방법

- 전체 데이터 또는 특정 하나의 데이터를 다룰 때 처럼, 리소스를 식별하기 위해 사용

Query Parameter

/users?user_id=10

- 데이터를 정렬하거나 필터링하는 경우 적합

2-23 JSON과 비동기통신 실습 (NoSQL 설계 기초)

1. JSON이란?

- Javascript Object Notation

- 자바스크립트 객체 문법에 토대를 둔 문자 기반의 데이터 교환 형식

 

- 자바스크립트 객체 리터럴 작성법을 따르는 구조

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

2. 메서드

- 자바스크립트 객체 -> JSON / JSON -> 자바스크립트 객체로 파싱하는 과정

JSON.stringify()
자바스크립트 객체 -> JSON 문자열 변환
console.log(JSON.stringify({ x: 5, y: 6 }));
// Expected output: "{"x":5,"y":6}"

console.log(JSON.stringify([new Number(3), new String('false'), new Boolean(false)]));
// Expected output: "[3,"false",false]"

console.log(JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }));
// Expected output: "{"x":[10,null,null,null]}"

console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// Expected output: ""2006-01-02T15:04:05.000Z""
JSON.parse()
JSON 문자열 -> 자바스크립트 객체 
const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);

console.log(obj.count);
// Expected output: 42

console.log(obj.result);
// Expected output: true

- 네트워크 통신의 결과로 받아온 JSON문자열을 프로그램 내부에서 사용하기 위해 JS 객체로 변환할 때 사용

3. JSON.placeholder

- 가짜 서버 (= fake, mock)로 JSON 기반 DB통신

import "./App.css";
import { useEffect, useState } from "react";

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((response) => {
        console.log();
        console.log("response.json()", response);
        return response.json();
      })
      .then((json) => {
        console.log("json", json);
        setData([...json]);
      });
  }, []);

  return (
    <div>
      {data.map((item) => {
        return (
          <div
            style={{
              border: "1px solid black",
              margin: "3px",
            }}
            key={item.id}
          >
            <ul>
              <li>userId : {item.userId}</li>
              <li>id : {item.id}</li>
              <li>title : {item.title}</li>
              <li>body : {item.body}</li>
            </ul>
          </div>
        );
      })}
    </div>
  );
}

export default App;