한입 크기로 잘라 먹는 리액트 Section 3

yiseonline·2023년 5월 15일
0

udemy study

목록 보기
3/7
post-thumbnail

3.1 Truthy & Falsy

js는 분리형을 넣지 않아도 참거짓을 분류해줌 -> 그걸 Truthy & Falsy라고 한다

const getName = (person)=>{
  return person.name;
}
let person = {name : "이서연"}; //객체 생성
const name = getName(person); //이서연이 name에 들어감

3.2 삼항 연산자

let a =3;
if(a>=0){
  console.log("양수");
}else{
  console.log("음수");
}

이거를

let a =3;
a>=0?console.log("양수"):console.log("음수");

이렇게 줄일 수 있따!

삼항연산자
~이면?~해라:(아니면)~해라

let a = [];

if(a.length ===0){
  console.log("빈 배열");
}else{
  console.log("안 빈 배열");
}

이거를

let a = [];

a.length ===0?console.log("빈 배열"):console.log("안 빈 배열");

로 짧게 할 수 있드아

let a = [];

 a.length === 0 ? "빈 배열" : "안 빈 배열";
console.log(arrayStatus);

콘솔을 안 쓰고 그냥 값을 집어넣으면 경고메시지를 준다

let a = [];

const arrayStatus = a.length === 0 ? "빈 배열" : "안 빈 배열";
console.log(arrayStatus);

그럴땐 이렇게 const와 같은 거로 저장해야한다.

삼항 연산자에도 truthy&falsy가 적용됨

let a; //undefined여서 falsy 
const result = a?true:false;
console.log(result); //false가 나온다
let a =[]; //빈 배열은 truthy
const result = a?true:false;
console.log(result); //true가 나온다

삼항 연산자를 중첩으로 쓸 수 있따

//TODO : 학점 계산 프로그램
let score = 100;

score>=90?console.log("A+"):score>=50?console.log("B+"):console.log("F");

ㄴ 근데 이건 보기에 너무 힘드니까 이럴땐 그냥 if문으로 ㅎㅏ자


3.3 단락회로 평가

단락회로 평가
-> 두개 이상의 피연산자가 있을 때 하나만 보고 평가한 후에 나머지 피연산자들은 안봐도 되는거

const getNmae = (person) => {
  if (!person) {
    return "객체가 아님";
  }
  return person.name;
};

let person;
const name = getNmae(person);
console.log(name);

truthy 예제

const getNmae = (person) => {
  const name = person && person.name; //이서연 저장
  return name || "객체가 아닙니다"; //name만 봐도 truthy
};

let person = { name: "이서연" };
const name = getNmae(person);
console.log(name);

falsy 예제

const getNmae = (person) => {
  const name = person && person.name; //이서연 저장
  return name || "객체가 아닙니다"; //name만 봐도 truthy
};

let person = null;
const name = getNmae(person);
console.log(name);

3.4 조건문 업그레이드

function isKoreanFood(food) {
  if (food === "불고기" || food === "비빔밥" || food === "떡볶이") {
    return true;
  }
  return false;
}

const food1 = isKoreanFood("불고기");
const food2 = isKoreanFood("파스타");
console.log(food2);
console.log(food1);

이런거를

function isKoreanFood(food) {
  if (["불고기", "떡볶이", "비빔밥"].includes(food)) {
    return true;
  }
  return false;
}

const food1 = isKoreanFood("불고기");
const food2 = isKoreanFood("파스타");
console.log(food2);
console.log(food1);

includes를 사용해서 간략히 바꿀 수 있다

배열.includes -> 배열안에 있으면 true 없으면 false를 반환해줌

식사 종류를 말하면 그 종류의 대표 메뉴를 반환하는것

const getMeal = (mealType) => {
  if (mealType === "한식") return "불고기";
  if (mealType === "양식") return "파스타";
  if (mealType === "중식") return "멘보샤";
  if (mealType === "양식") return "초밥";
  return "굶기";
};
console.log(getMeal("한식"));
console.log(getMeal("중식"));

객체의 괄호 표기법으로 바꿀 수도 있ㅇ음

const meal = {
  한식: "불고기",
  중식: "멘보샤",
  양식: "스테이크",
  일식: "초밥",
  인도식: "카레"
};

const getMeal = (mealType) => {
  return meal[mealType] || "굶기";
};
console.log(getMeal("한식"));
console.log(getMeal());

3.5 비 구조화 할당 (구조 분해 할당)

비구조화 할당 -> 배열의 값을 순서대로 할당 받는것

let arr = ["one", "two", "three"];

let [one, two, three] = arr; //배열 값을 순서대로 할당 받아서
 
console.log(one, two, three); //출력이 가능하다

배열의 선언 분리 비구조화 할당

let [one, two, three] = ["one", "two", "three"];
console.log(one, two, three); 

배열에 값을 더 추가하고 싶다면

let [one, two, three, four = "four"] = ["one", "two", "three"];
//배열 안에서 값을 선언하고
console.log(one, two, three, four); //배열 속에 넣어서 출력

swap

let a = 10;
let b = 20;

let temp = 0;
temp = a;
a = b;
b = temp;
console.log(a, b);

이거를

let a = 10;
let b = 20;

[a, b] = [b, a];
console.log(a, b);

이렇게 짧게 만들 수 있다

객체로 점표기법으로도 가능

let object = { one: "one", two: "two", three: "three" };

let one = object.one;
let two = object.two;
let three = object.three;

console.log(one, two, three);

객체를 비구조화 할당으로 해보기

let object = { one: "one", two: "two", three: "three" };

let { one, two, three } = object; //키 값을 기준으로 하는거여서 순서는 상관이 없다
console.log(one, two, three);

중간에 키값의 이름을 바꾸고 싶다면

let object = { one: "one", two: "two", three: "three", name: "이서연" };

let { name: myName, one, two, three } = object; //여기서 콜론으로 바꿔주면 된다
console.log(one, two, three, myName);

중간에 값을 추가하고 싶다면

let object = { one: "one", two: "two", three: "three", name: "이서연" };

let { name: myName, one, two, three, abc = "four" } = object;
//이렇게 abc='four' 처럼 추가해주자
console.log(one, two, three, myName, abc);

3.6 Spread 연산자

... -> spread 연산자임

const cookie = {
  base:'cookie',
  madeIn:'korea'
};
const chocoCookie = {
  ...cookie,
  toping:'chocochip'
};

console.log(chocoCookie);

이렇게 코드 짜면

이렇게 잘 나옴

spread연산자 = 객체의 값을 새로운 객체에 펼쳐주는 역할

const cookie = {
  base: "cookie",
  madeIn: "korea"
};
const chocoCookie = {
  ...cookie,
  toping: "chocochip"
};
const blueberryCookie = {
  ...cookie,
  toping: "blueberry"
};
const strawberryCookie = {
  ...cookie,
  toping: "strawberry"
};
console.log(chocoCookie);
console.log(blueberryCookie);
console.log(strawberryCookie);

여러개로도 할 수 있다

배열안에서도 쓸 수 있다!!

const noTopingCookies = ["촉촉한쿠키", "안촉촉한 쿠키"];
const topingCookies = ["바나나쿠키", "블루베리쿠키", "딸기쿠키", "초코칩쿠키"];

const allCookies = [...noTopingCookies, ...topingCookies];
console.log(allCookies);


ㄴ 결과값

값을 중간에 추가할 수도 있다

const noTopingCookies = ["촉촉한쿠키", "안촉촉한 쿠키"];
const topingCookies = ["바나나쿠키", "블루베리쿠키", "딸기쿠키", "초코칩쿠키"];

const allCookies = [...noTopingCookies, "함정쿠키", ...topingCookies];
console.log(allCookies);


ㄴ 결과값


3.7 동기식 & 비동기식

연산과정을 처리하는 애 -> thread
블로킹방식 -> 내가 작업하고 있ㄴ으니까 아무것도 못해!


비동기식 작업 -> 여러 작업을 동시에 하는 작업 방식
논블로킹방식 -> 하나의 작업이 쓰레드를 점유하지 않는, 다른 작업을 할 수 있는 방식

동기식 방식

//동기적 방식
function taskA(){
  console.log("A 작업 끝");
} 
taskA(); //함수가 구동이 완료되기 전엔
console.log("코드 끝"); //콘솔로그가 진행되지 않기 때문

비동기식 방식

//비동기적 방식
function taskA() {
  setTimeout(() => {
    console.log("A TASK END");
  }, 2000);
}
taskA(); 
console.log("코드 끝"); 


task가 끝날 때 까지 기다리지 않고 그냥 콘솔로그 해버린다

//동기적 방식
function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b; //지역 상수에 저장
    cb(res); //콜백함수
  }, 3000);
}
function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}

taskA(3, 4, (res) => {
  console.log("A TASK RESULT : ", res);
});
taskB(7, (res) => {
  console.log("B TASK RESULT : ", res);
});
console.log("코드 끝");


왜 B가 A보다 일찍 나오냐면
taskB는 1초만 기다리지만 taskA는 3초 기다리기 때문

//동기적 방식
function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b; //지역 상수에 저장
    cb(res); //콜백함수
  }, 3000);
}
function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}
function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000);
}
taskA(3, 4, (res) => {
  console.log("A TASK RESULT : ", res);
});
taskB(7, (res) => {
  console.log("B TASK RESULT : ", res);
});
taskC(14, (res) => {
  console.log("C TASK RESULT : ", res);
});

console.log("코드 끝");


ㄴ 결과값


결국 call stack에서 one, two,three 함수가 없어지고 마지막에 main Context가 제거되면서 프로그램이 끝난다

비동기 처리 방법

여기서 setTImeout()은 오ㅐ 빨강색이냐면 비동기 함수이기 ㄸㅐ문
자바스크립트는 이런 비동ㅅ기 함수는 web API에 넘겨버림

asyncAdd()가 끝나서 제거가 되고 cb함수가 API에서 call back queue로 옮겨짐 그 후에 수행이 이루어져서 event loop이 callback에 아무것도 없는지 확인하다가 없으면 call stack으로 넘겨줌

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b; //지역 상수에 저장
    cb(res); //콜백함수
  }, 3000);
}
function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}
function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000);
}
taskA(4, 5,(a_res) => {
  console.log("A RESULT : ", a_res);
  taskB(a_res, (b_res) => {
    console.log("B RESULT : ", b_res);
    taskC(b_res, (c_res) => {
      console.log("C RESULT : ", c_res);
    });
  });
});
console.log("코드 끝");

하...
아니 왜 난 자꾸 오류뜨냐 개똑같은데
새로고침 하니까 됐당 ㅎ


ㄴ 결과값 (이건 가독성이 너무 구림 / 콜백에 콜백에 콜백... 이 콜백 지옥에 빠지면 안됨 이거를 다음 강의 때 다룰 것)


3.8 Promise | 콜백 지옥 탈출

비동기 작업이 가질 수 있는 3가지 상태

pendnig - 비동기 작업이 대기하거나 시작할 수 없는 문제가 발생한 상태
fulfilled - 비동기 작업이 정상적으로 완료된 상태
rejected - 비동기 작업이 실패한 상태

성공한 예시

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    //number가 숫자가 아니면 실패 숫자면 성공
    if (typeof number === "number") {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  }, 2000);
}

isPositive(
  10,
  (res) => {
    console.log("성공적으로 수행됨 : ", res);
  },
  (err) => {
    console.log("실패하였음 : ", err);
  }
);

실패한 예시

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    //number가 숫자가 아니면 실패 숫자면 성공
    if (typeof number === "number") {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  }, 2000);
}

isPositive(
  [], //배열로 해서 숫자형으로 안 함
  (res) => {
    console.log("성공적으로 수행됨 : ", res);
  },
  (err) => {
    console.log("실패하였음 : ", err);
  }
);

resolve돼서 call back함수로 들어옴

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    //number가 숫자가 아니면 실패 숫자면 성공
    if (typeof number === "number") {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  }, 2000);
}

function isPositivep(number) {
  const executor = (resolve, reject) => {
    //executor - 비동기 작업을 실질적으로 수행하는 함수
    setTimeout(() => {
      if (typeof number === "number") {
        //성공 -> resolve
        console.log(number);
        resolve(number >= 0 ? "양수" : "음수");
      } else {
        //실패 -> reject
        reject("주어진 값이 숫자형 값이 아닙니다");
      }
    }, 2000);
  };
  const asyncTask = new Promise(executor);
  //promise객체 생성해서 executor을 넘겨주면 자동으로 executor가 실행된다
  return asyncTask;
}
const res = isPositivep(101);
res
  .then((res) => {
    console.log("작업 성공 : ", res);
  })
  .catch((err) => {
    console.log("작업 실패 : ", err);
  });

//어떤 함수가 promise를 반환한다는 것은 이 함수가 비동기 작업을 하고
// 그 작업에 결과를 promise 객체로 반환받아서 사용할 수 있다는 뜻

ㄴ 여기선 작업 성공 을 then에서 실행됨

reject 실행하는 거

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    //number가 숫자가 아니면 실패 숫자면 성공
    if (typeof number === "number") {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  }, 2000);
}

function isPositivep(number) {
  const executor = (resolve, reject) => {
    //executor - 비동기 작업을 실질적으로 수행하는 함수
    setTimeout(() => {
      if (typeof number === "number") {
        //성공 -> resolve
        console.log(number);
        resolve(number >= 0 ? "양수" : "음수");
      } else {
        //실패 -> reject
        reject("주어진 값이 숫자형 값이 아닙니다");
      }
    }, 2000);
  };
  const asyncTask = new Promise(executor);
  //promise객체 생성해서 executor을 넘겨주면 자동으로 executor가 실행된다
  return asyncTask;
}
const res = isPositivep([]);
res
  .then((res) => {
    console.log("작업 성공 : ", res);
  })
  .catch((err) => {
    console.log("작업 실패 : ", err);
  });

//어떤 함수가 promise를 반환한다는 것은 이 함수가 비동기 작업을 하고
// 그 작업에 결과를 promise 객체로 반환받아서 사용할 수 있다는 뜻


ㄴ 배열을 넣어서 숫자형으로 안했더니 reject가 실행되고 reject에 맞는 값이 catch함수로 넘어가서 실행된다 !

요놈의 콜백 지옥을 없애려고

taskA(3, 4, (a_res) => {
  console.log("task A : ", a_res);
  taskB(a_res, (b_res) => {
    console.log("task B : ", b_res);
    taskC(b_res, (c_res) => {
      console.log("task C : ", c_res);
    });
  });
});

이렇게 바꿈

function taskA(a, b, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

taskA(5, 1).then((a_res) => {
  console.log("A RESULT : ", a_res);
  taskB(a_res).then((b_res) => {
    console.log("B RESULT : ", b_res);
    taskC(b_res).then((c_res) => {
      console.log("C RESULT : ", c_res);
    });
  });
});

ㄴ 근데 콜백 지옥이 있네? 뭐야

그래서 또 이렇게 해따
then 메소드 사용하기

function taskA(a, b, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

taskA(5, 1)
  .then((a_res) => {
    console.log("A RESULT : ", a_res);
    return taskB(a_res); //b의 promise 받은거
  })
  .then((b_res) => {
    console.log("B RESULT : ", b_res);
    return taskC(b_res); //c의 promise 받은거
  })
  .then((c_res) => {
    console.log("C RESULT : ", c_res);
  });

비동기 처리 호출 코드와 결과를 처리하는 코드를 분리해줄 수 있다

const bPromiseResult = taskA(5, 1).then((a_res) => {
  console.log("A RESULT : ", a_res);
  return taskB(a_res); //b의 promise 받은거
});
//ㄴ 여기는 호출 부분

// ㄱ 여기는 결과 처리 부분
console.log("ahd");
//이렇게 콘솔을 해도 a,b,c는 잘 나온다
bPromiseResult
  .then((b_res) => {
    console.log("B RESULT : ", b_res);
    return taskC(b_res); //c의 promise 받은거
  })
  .then((c_res) => {
    console.log("C RESULT : ", c_res);
  });

3.9 asnc / await | 직관적인 비동기 처리

//async

function hello() {
  return "hello";
}

async function helloAsync() {
  return "hello Async";
}

console.log(hello());
console.log(helloAsync());

ㄴ 이렇게 하면

async는 이상한 값이 나옴

왜냐?
helloAsync는 promise를 리턴하고 있음..
async를 함수에 붙이면 그 함수는 자동적으로 promise를 반환하는 함수가 된다

//async

function hello() {
  return "hello";
}

async function helloAsync() {
  return "hello Async";
}

helloAsync().then((res) => {
  console.log(res);
});


이렇게 하면 잘 나온다

helloAsync에 값이 res에 들어와서 console되는 것 !

function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  await delay(3000);
  return "hello async";
}

helloAsync().then((res) => {
  console.log(res);
});

await이란 키워드를 비동기 함수 앞에 붙이게 되면 이 비동기 함수가 마치 동기적인 함수처럼 작동함
= 뒤에 있는 함수가 끝나기 전까지 그 아래있는 코드를 수행하지 않는다 !

(await은 async가 붙은 함수 안에서만 사용할 수 있다)

function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  await delay(3000);
  return "hello async";
}

async function main() {
  const res = await helloAsync();
  console.log(res);
}

main();

ㄴ 이거 역시 main을 추가해 보았음
비동기를 동기식으로 처리해보려구


3.10 API & fetch

API =>

자바스크립트로 개발하는 관점에선 우리가 client이다

1,4 => API 호출
api = client와 server를 이어주게 도와주는 것

fetch = js에서 api호출을 할 수 있도록 도와주는 내장함수

let response = fetch("https://jsonplaceholder.typicode.com/posts").then((res) =>
  console.log(res)
);

.....

똑같은데 왜이러는거지...???

async function getData() {
  let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts");
  let jsonResponse = await rawResponse.json();
  console.log(jsonResponse);
}

getData();

fetch로 api 불러와서 함수 호출 하면

api 창에서 봤던 객체들이 나온드아

0개의 댓글