/*
자바스크립트의 특징을 이용한 boolean 값을 넣지 않아도 참이나 거짓으로 나오는 속성이 있다.
truthy : true 같은 값
ex. [](빈배열),{}(객체리터럴), 숫자, "0", "false"(문자열), Infinity
falshy : false 같은 값
ex. ""(빈문자), undefined(null과의 차이: 변수에 아무것도 할당하지 않은 값) , null, 0, -0, NaN
*/
let a = "0";
if (a) console.log("true");
else console.log("false");
/* 이걸 어떻게 활용할까? */
const getName = (person) => {
if (!person) { //true가아니면 들어와라!
return "객체가 아닙니다" // 예외처리
}
return person.name;
};
let person = { name: "이경미" }; //person변수에 객체 저장
let undef; //변수 선언 후 값을 안넣었으니, 당연히 undefined
const name = getName(person); //함수 호출후, 변수 name에 저장
const name2 = getName(undef);
console.log(name); //값이 찍힘
console.log(name2); //undefined도 에러나지 않게 예외처리 필요!
// 예외처리 할때 아주 유용!
/* 양수/ 음수 확인 */
let a = 3;
let con = (a > 0) ? console.log("양수") : console.log("음수");
/* 빈 배열인지 확인 */
let b = [];
b.length === 0 ? console.log("빈 배열!") : console.log("배열에 값이 있다!");
//값에 넣어서도 사용가능!
let c; // undefined , falsy값
let d = []; // truthy값
const result = c ? true : false; // false 반환
const result2 = d ? true : false; // true 반환
console.log(result);
console.log(result2);
/* 성적 표기 프로그램(중첩 삼항 연산자) - 가독성 떨어진다, if가 나음! */
// 90점 이상이면 A+, 50점 이상이면 B+, 둘다 아니면 F
let score = 90;
// const my_score = score >= 90 ? "A+"
// : score >= 50 ? "B+" // 첫번째 조건이 아니면 한번 더 비교
// : "F"; // 그것도 아니면 한번 더 비교
/*if 조건문으로 변경*/
let my_score;
if (score >= 90) my_score = "A+";
else if (score >= 50) my_score = "B+";
else my_score = "F";
console.log(my_score);
/* 단락 회로 평가 : 왼쪽에서 오른쪽으로 연산하는 순서를 이용한 문법임!*/
console.log(false && true); //&&는 둘다 true여야 t이므로, false 보자마자 바로 false 반환
console.log(true || false); //||는 하나만 true여도 t이므로, true 보자마자 바로 true 반환
/* 단락 회로 평가 간지나게 이용하기 */
const getName = (person) => {
// if (!person) return "객체가 아닙니다";
// return person.name;
const name = person && person.name;
//(객체 있을 경우) name에는 &&연산자로인해, 두 조건다 확인후 person.name값인 dlrudal 반환
//(객체 없을 경우) &&연산자로 인해, flase이므로, null값 담김
return name || "객체가 아닙니다.";
//(객체 있을 경우) ||는 하나만 t여도 반환하므로 dlrudal 반환
//(객체 없을 경우) ||는 두개다 t여야 반환이므로 뒤 조건까지 확인 후 "객체가 아닙니다" 반환
};
// let person = { name: "dlrudal" };
let person = null;
const name = getName(person);
console.log(name);
/*여러개의 조건일때 조건에 맞으면 t / 아니면 f를 반환하는 함수*/
function isKoreanFood(food) {
if (["불고기", "떡볶이", "비빔밥"].includes(food)) {
return true;
}
return false;
}
console.log(isKoreanFood("불고기"));
console.log(isKoreanFood("파스타"));
/* 많은 유형을 조건식으로 반환해야 할 때 유용하게 사용 가능 - 객체 이용*/
const meal = {
한식: "불고기",
중식: "멘보샤",
일식: "초밥",
양식: "파스타",
인도식: "카레"
};
const getMeal = (mealType) => {
return meal[mealType] || "굶기";
}
// function getMeal(mealType) {
// return meal[mealType] || "굶기";
// }
console.log(getMeal("중식"));
console.log(getMeal());
/*
- 비구조화 할당: 배열이나 객체의 속성 혹은 값을 해체하여 그 값을 변수에 각각
담아 사용하는 자바스크립트 표현식.
*/
/* 배열의 비구조화 할당 */
let arr = ["one", "two", "three"];
let [one, two, three] = arr;
// let [one, two, three] = ["one", "two", "three"];
// let one = arr[0] 이랑 같은 말, 변수에 값 담는 것
console.log("배열 비구조화 할당")
console.log(one, two, three)
/*배열의 비구조화 할당 (기본값)*/
let [four, five, six, seven = 7] = [4, 5, 6];
console.log(four, five, six, seven); // seven은 할당 안해주면 undefined
//sevne = 7 이런식으로 기본값 바로 할당해주는 것 가능
/* swap !! */
/*원래 방식*/
let a = 20;
let b = 10;
let tmp = 0;
tmp = a;
a = b;
b = tmp;
console.log("a,b의 값" + a, b);
/*배열 비구조화 방식 이용*/
let c = 20;
let d = 10;
[c, d] = [d, c]
console.log(c, d)
/* 객체의 비구조화 할당(리액트에서 중요!!!!) */
console.log("객체의 비구조화 할당");
let object = { one1: "one", two2: "two", three3: "three" };
let { one1, two2, three3, four4 = "four" } = object; //기본값 할당 가능
console.log(one1, two2, three3, four4);
//배열에서 비구조화 할당을 사용할 경우, 좌항의 각 변수에는 같은 인덱스 가진 우항의 값 할당
//객체는 키값을 기준으로 할당한다.(우항의 키값이 좌항의 변수명과 매칭), 즉 같은 이름 사용해야!
// 순서도 상관없다, 키값 기준으로 가져옴!
/* + 객체의 키값 대신 변수명 사용하기 */
let { name: user_name, age: user_age, gender: user_gender }
= { name: "이경미", age: 26, gender: "여" }
console.log(user_name, user_age, user_gender);
// 객체의 프로퍼티 값은 d 이런식의 "" 없는 값을 할당하려고 하면 변수로 인식함.
/* script 연산자 : 중복된 요소들이 많을때 쓰는 방법
spread: 펼쳐주다!, 즉 객체의 중복되는 요소들을 펼쳐줄때!
주로 객체, 배열의 복사, 연결의 용도로 활용도가 높다!
*/
//Object
const cookie = { base: "cookie", madIn: "Korea" };
const chocoCookie = { ...cookie, toping: "chocho" };
const strawberryCookie = { ...cookie, toping: "strawberry" };
console.log(chocoCookie, strawberryCookie); // cookie가 전부 복사된걸 볼 수 있다!
//Array
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [...arr1, 6, 7, "히히", 8, 9];
console.log(arr2); // arr1+arr2가 사용된 것을 볼 수 있다.
//String -> Array
let string = "abcdefg";
let arr = [...string];
console.log(arr);
-> 자바스크립트는 싱글 스레드로 동작한다
-> 그럼 스레드를 분할해서 넣으면 되겠네!, 하지만 자바스크립트는 싱글 스레드로 동작함!
🙋♀️비동기 방식으로 한번에 처리해버리면, 어떤 일이 언제 끝났는지 어떻게 알지?
콜백함수를 사용하면 됨
실습
/* 동기와 비동기 */
/* 동기 방식 */
console.log("**동기 방식**");
function taskA() {
console.log("A 작업 끝");
}
taskA();
console.log("코드 끝"); //a 작업이 끝날때까지는 "코드 끝"이라는 코드를 읽을수 없음(동기처리)
/* 위 코드를 비동기 방식으로 바꿔보기 */
console.log("**비동기 방식**");
//setTimeout : 자바스크립트에서 제공하는 비동기 함수
function taskB() {
setTimeout(() => { console.log("A Task End") }, 2000);
} // 2초후 실행
taskB();
console.log("코드 끝");
/* 비동기 처리의 결과값을 콜백함수로 전달해서 이용하기 */
console.log("**비동기 방식+콜백함수**");
function taskC(a, b, cb) {
setTimeout(() => {
const res = a + b; //우린 a+b 값을 밖에서도 알아보길 원함
cb(res); // function으로 들어가서 결과값 나옴 cb(7)인거처럼!
}, 2000);
}
taskC(3, 4, (res) => { console.log("2초후에 나오는 결과" + res) }) //나중에 실행
console.log("코드 끝"); // 먼저 실행되고
/* 1초 뒤에 전달받은 파라미터 값 *2 하는 함수 만들기 */
function double(a, cb) {
setTimeout(() => {
const res = a * 2;
cb(res);
}, 1000);
}
double(3, (res) => {
console.log("1초 후에 나오는 결과" + res);
});
->setTimeOut 특성상 console창 보기 어려워서 첨부 안함! 직접 복붙해서 넣어본 뒤 확인해보자~
-main context : 자바스크립트 최상위 문맥임, 가장 먼저 들어온다. (= 프로그램이 시작되는 시점임, main context가 나간다면 프로그램 종료되는 시점)
1) asyncAdd함수 실행되면서 call Stack에 들어오고
2) setTimeout()실행되는데, 바로 callstack에 안들어온다
-> asyndAdd() 먼저 끝나고
-> callback Queue로 옮겨지고
-> callStack으로 옮겨간다!
/* 비동기 프로그램 만들기 */
function taskD(a, b, cb) {
setTimeout(() => {
const res = a + b;
cb(res);
}, 3000)
}
function taskE(a, cb) {
setTimeout(() => {
const res = a * 2;
cb(res)
}, 1000)
}
function taskF(a, cb) {
setTimeout(() => {
const res = a * -1;
cb(res)
}, 2000)
}
taskD(4, 5, (a_res) => {
console.log("D REULST", a_res);
taskE(a_res, (b_res) => {
console.log("E RESULT", b_res);
taskF(b_res, (c_res) => {
console.log("F RESULT", c_res);
})
})
}) //콜백지옥임...
console.log("코드 끝")
/* 콜백지옥을 해결할 수 있는 비동기처리 객체! */
// resolve - 성공 , reject - 실패
function isPositive(number, resolve, reject) {
//비동기로 해줄거라 setTimeout 걸어줌
setTimeout(() => {
if (typeof number === "number") {
console.log(number);
resolve(number >= 0 ? "양수" : "음수")
} else {
reject("주어진 값이 숫자형 값이 아닙니다.")
}
}, 2000)
}
// 콜백을 이용한 비동기 처리
// isPositive(
// [],
// (res) => {
// console.log("성공적으로 수행함:", res);
// },
// (err) => {
// console.log("실패하였음:", err)
// }
// )
// promise를 이용한 비동기 처리
function isPositiveP(number) {
const executor = (resolve, reject) => { //executor 실행자
setTimeout(() => {
if (typeof number === "number") {
console.log(number);
resolve(number >= 0 ? "양수" : "음수");
} else {
reject("주어진 값이 숫자형 값이 아닙니다.")
}
}, 2000)
}
const asyncTask = new Promise(executor);
// promise 객체 생성해서, promise의 실행으로 executor 함수를 넘겨주면,
// 전달하는 순간 자동으로 executor 함수 수행됨
return asyncTask; // 반환값이 promise 임
}
isPositiveP(101);
/* promise 객체 사용해보기
1. 변수에 담기
2. 변수. then(콜백함수).catch(콜백함수)
(promise객체의 메서드인 then 과 catch 사용한것!)
*/
const res = isPositiveP([]);
res.then((res) => { console.log("작업성공:", res) }).catch((err) => { console.log("작업실패:", err) })
//resolve 실행시 -> then에서 받아오고 ,
//reject 실행시 -> catch에서 받아온다.
/*
비구조화할당에서 했던 예제를 => promise로 간단하게 바꾸기
promise를 반환하는 함수로 바꾼 이유 :
그 함수가 비동기적으로 동작하고, 반환한 promise 객체 이용해서 비동기처리의 결과값을 then, catch로 이용할수 있다!
*/
function taskA(a, b) { // 콜백함수 지우면 됨
return new Promise((resolve, reject) => {
// executor 변수 만들어서, promise 객체에 넣어준거랑 같음!
setTimeout(() => {
const res = a + b;
resolve(res); // then에서 받을 수 있음
}, 3000)
})
}
function taskB(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const res = a * 2;
resolve(res);
}, 1000)
})
}
function taskC(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const res = a * -1;
resolve(res);
}, 2000)
})
}
//-> 이런식으로 쓰면 콜백함수 쓰는것과 다를 바 없다.
// taskA(5, 1).then((a_res) => { //then은 reslove 됐을때
// 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 쓰는 방식 , (then 체이닝 방식)
const bPromiseResult = taskA(5, 1)
.then((a_res) => {
console.log("a result:", a_res);
return taskB(a_res); // promise 객체인 a_res값이 담겨서 return됨 taskB 호출
})
// 호출부와
console.log("중간에 이런것도 넣을 수 있답니다")
bPromiseResult //결과부 나눠서 쓸수도 있고, 중간에 추가도 가능하다!
.then((b_res) => {
console.log("b result:", b_res);
return taskC(b_res);
})
.then((c_res) => {
console.log("c result:", c_res);
})
// typeA(3, 4, (a_res) => {
// console.log("TYPE A:", a_res);
// typeB(a_res, (b_res) => {
// console.log("TYPE B:", b_res);
// typeC(b_res, (c_res) => {
// console.log("TYPE C:", c_res)
// })
// })
// })
->js 는 기본적으로 동기식이지만, api 요청보낼때 응답이 올 때 까지 마냥 기다릴수 만은 없기 때문에 비동기 처리가 필요하다! (동기처리방식으로만 사용한다면 모든 순서가 다 끝날때까지 기다려야한다!)
✏️ 하지만 비동기처리방식을 사용한다면, 의도하지 않은 순서로 함수가 실행될 수 있기때문에 원하는 부분에서 동기방식으로 변환해줘야함!!
해결방법 1️⃣: 콜백함수
-콜백함수 : 함수 안에서 또 다른 함수를 호출하는 것!
(but, 여러 함수를 순서대로 호출할 필요가 있을 경우, 콜백 지옥을 경험 !)
해결방법 2️⃣: promise객체
보통의 식
const promise = new Promise((resolve, reject) => {구현식});
// promise를 이용한 1초 뒤 성공하는 상황 구현!
function success() {
//function으로 사용한다면 return 해줘야 함수 밖에서도 값 알아볼 수 있으므로
return new Promise((resolve, reject) => {
setTimeout(() => {
//성공하려면 뭐가 필요해? resolve
resolve("성공");
}, 1000)
})
}
// 성공시 then메소드(콜백) 해서 구현해준다!
success().then((n) => console.log(n)); // then함수 활용해서 resolve 호출해서 console로 찍음
//promise를 이용해 1초 뒤 실패하는 상황 구현
function fail() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error()) // "실패"라고 해줘도 상관없다.
}, 1000)
})
}
fail().catch((n) => { console.log(n) })
-> 요런 형태가 callback hell!
/* async / await - 직관적인 비 동기 처리 코드 작성하기*/
// async
function hello() {
return 'hello';
}
//async 키워드 붙여주면 자동으로 promise 리턴하는 비동기 처리 함수가 된다!
async function helloAsync() { //helloAsync에 마우스 커서 올려보면 => promise 반환하는 것 알수 있음!
return 'hello Async';
}
console.log(hello(), helloAsync());
// promise 객체로 return 한다는 소리는 => then 쓸수 있다는 소리!
helloAsync().then((res) => {
console.log(res) // res 어디서 옴? async 키워드 붙이면 resolve(res)와 같은 효과를 냄!(return)
})
/* await */
//전달받은 파라미터만큼 delay 되는 함수 만들거다!
function delay(ms) {
// return new Promise((resolve)=>{
// setTimeout(()=>{
// resolve(); setTimeout 함수 안에 resolve 호출말고 없으면, 그냥 resolve 만 써줘도 된다.
// },ms)
// })
return new Promise((resolve) => {
setTimeout(resolve, ms);
})
}
async function newAsync() {
// return delay(3000).then(() => { return "hello newAsync" })
await delay(3000); // await키워드가 붙은 함수의 호출은 함수가 끝나기 전까지
// 아래있는 코드 수행 안함(동기처리 한다는 뜻)
//await은 async 키워드가 있어야만 사용가능!
return "hello newAsync"
}
//main에서 hello newAsync 출력해보자!
async function main() {
const res = await newAsync();
console.log(res);
}
main();
newAsync().then((res) => {
console.log(res);
})
-> dummy data 쓸수있는 사이트
//fetch 함수: 자바스크립트에서 api 호출 돕는 내장함수
let response = fetch('https://jsonplaceholder.typicode.com/posts')
.then((res) => console.log(res)) //promise 반환하는 함수
// 결과값은 객체로 나옴.(선물의 포장지같은 개념, 포장지 안을 뜯어서 확인해야함!)
// dummy data는 json형태로 되어있음
async function getData() {
let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts");
let jsonResponse = await rawResponse.json();
console.log(jsonResponse);
}
getData();