Javascript with 드림코딩 3

커피 내리는 그냥 사람·2021년 4월 16일
0

기업협업 인턴십

목록 보기
8/16

전반적인 개념을 잡고 가자

1. JSON 개념 정리 와 활용방법

1. JSON to...

const rabbit = {
  name : 'tori',
  color : 'white',
  size : null,
  birthday : new Date(),
  jump:()=>{ console.log(`${name} can jump!`);
        },
  
};


// object to JSON
json = JSON.stringify(rabbit);
console.log(json)

// JSON to object
json = JSON.stringify(rabbit)
const obj = JSON.parse(json)
console.log(obj)
  1. 단 jump라는 메서드는 없음..(함수)

  2. obj는 string이라 이런거 안 됨

console.log(rabbit.birthday.getDate()) - 29
console.log(obj.birthday.getDate()) -> type error

그럼 어떻게 해?

// JSON to object
json = JSON.stringify(rabbit)
const obj = JSON.parse(json, (key, value) => {
  console.log(`key : ${key}, value : ${value}`)
return key === 'birthday' ? new Date(value) : value;
});

console.log(obj)

console.log(rabbit.birthday.getDate())
console.log(obj.birthday.getDate())

2. callback

  • 자바스크립트는 동기적이다.
  • 순서적이다.
  • Hoisting??? : var, function dec한 것이 가장 위로 올라가는 것.호이스팅 된 이후부터 코드가 나타나는 순으로 자동 실행

    선언에 상관 없이 가장 위로 끌어 올려주어 실행시키는 것.

1. callback 함수 :

참고 블로그
참고 블로그
참고 영상
참고 영상

비동기 함수들이 동작하고 있을 때 setTimeout 안에 이름 없는 함수 같이 다음 동작을 위해서 기다리고 있는 함수

  • example 1
console.log("1")

setTimeout(() => {
  console.log("2");
}, 1000)
// 1초 뒤에 실행하래!
console.log("3")

순서 : 비동기적, 1, 3, 2

  • example2
function first(a,b,callback){
	let v=a*b;
	callback(v);
}

first(1,2,function(v){
	console.log(v);		//2
})
  • example3
function task(){
  let val = 1+2;
  console.log(val)
}
function atask(){
  // atask는 setTimeout, 즉 예약 거는 것만 함(셋타임 실행)
  setTimeout(function(){
      let val = 1 + 2;
  console.log(val)
    // 얘는 setTimeout이 찍어줌.
  }, 1000);
  // 1초 후에 안에 함수를 실행하달라고 예약하는 코드
  // 예약 걸고 실행하고 하니까 end보다 늦게 뜨는게 맞음
}

atask();
// end가 먼저 찍힘
console.log('end')
// end는 task가 종료되지 않으면 실행할 수 없음
  • 내가 만들어 본 예제
function test (a, b) {
  let result = a + b
  console.log(result)
  
  setTimeout(
  function(){
    console.log("Wait!");
  }, 5000)
}

test(1, 3)

2. 정리 : "나중에 다시 불러줘"

  • 근데 꼭 비동기일때만 써? -> No
  1. 동기적
  2. 비동기적

3. 콜백 지옥 체험

1. setting

class UserStorage {
    loginUser(id, password, onSuccess, onError){
      setTimeout(()=>{
        if (
          (id === 'ellie' && password === 'dream')||
          (id === 'coder' && password === 'academy')
          ){
          onSuccess(id);
        }else{
          onError(new Error('not found'));
        }
      }, 2000)
    }
    getRoles(user, onSuccess, onError){
      setTimeout(() => {
        if(user === 'ellie'){
          onSuccess({name : 'ellie', role : 'admin'});
  }else{
    onError(new Error('no access'))
  }
      }, 1000);
      
    }
  }

2. 통신 위한 코드 작성

const userStorage = new UserStorage();
  const id = prompt('enter your id');
  const password = prompt('enter your password');
  userStorage.loginUser(id, password, 
     (user)=>{
         userStorage.getRoles(user,userWithRole => {
             alert(`Hello, ${userWithRole.name}, You have a ${userWithRole.role}`)

         },
         error => {})
     },
    error =>{
        console.log(error)
    })

3. 문제점

  1. 콜백에 콜백에 콜백에 콜백에 콜백에 콜백에 콜백...... -> 비즈니스 로직 이해, 가독성 떨어짐
  2. 디버깅, 문제 분석이 어려움
  3. 유지보수가 어려움

비동기 코드를 어떻게 깔끔하게 정리할까? : 프로미스부터~

4. 근데 콜백 자체를 원래 안 쓰는건가?

논의 결과 프로젝트가 커질 경우 (비즈니스로직이 커질 경우) 위와 같은 이유가 생긴다는 것이지 아예 콜백 자체를 지양하자는 것은 아닌 것 같다.

3. promise

  • 비동기 코드 깔끔하게 처리하기

1. state(수행중? 끝?)

  • pending -> fullfilled or rejected

2. producer / consumer 차이

1. producer : resolve라는 콜백함수를 예시

const promise = new Promise((resolve, reject)=>{
    // doing some heavy work
    console.log('doing something')
  // 그 순간 바로 통신, 작업 시작
  // 사용자가 요청한 경우에만 해야하면..??! -> 불필요한 통신이 일어나버림..유의 ; setTimeout 등
})

2. Consumer

promise.then((value) => {
  console.log(value)
})

3. 그러면 reject?!

const promise = new Promise((resolve, reject)=>{
    // doing some heavy work
    console.log('doing something')
  setTimeout(()=>{
    reject(new Error('not network'));
  }, 2000);
})

promise.then((value) => {
  console.log(value)
})

>>> Uncaught (in promise) Error: not network

4. finally까지 플로우(promise 체이닝)

  • 파이썬 예외처리 생각해보기

5. 새로운 예시(비동기적인 것도 묶어서)

const fetchNumber = new Promise((resolve, reject) =>{
  setTimeout(() => resolve(1), 1000);
});

fetchNumber
.then(num => num*2)
.then(num => num*3)
.then(num => {
  return new Promise((resolve, reject)=>{
    setTimeout(()=> resolve(num-1), 1000);
  });
})
.then(num => console.log(num))
  1. 결과 값에 따라 입력 생략할 수 있는 케이스 & error 핸들링
  • 중간에 에러가 나면? :
catch(console.log)
  return (대체)

6. 콜백 개선

class UserStorage {
    loginUser(id, password){
        return new Promise((resolve, reject)=>{
            setTimeout(()=>{
                if (
                  (id === 'ellie' && password === 'dream')||
                  (id === 'coder' && password === 'academy')
                  ){
                  resolve(id);
                }else{
                  reject(new Error('not found'));
                }
              }, 2000);
        });

    }
    getRoles(user){
        return new Promise((resolve, reject)=>{
            setTimeout(() => {
                if(user === 'ellie'){
                  resolve({name : 'ellie', role : 'admin'});
          }else{
            reject(new Error('no access'))
          }
              }, 1000);
        })

      
    }
  }

const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your password');
  userStorage.loginUser(id, password)
  .then(user => userStorage.getRoles)
  .then(user=alert(`Hello, ${userWithRole.name}, You have a ${userWithRole.role}`))
  .catch(console.log)

4. async / await

  • Promise 를 간결하고 간편하게 만들어주는 역할
  • promise의 체이닝을 대신해서 비동기를 동기처럼 쓸 수 있게 해주는 것
  • 기존에 존재하는 promise에 간편한 API 식으로.. (syntactic sugar라고..)

1. async

function fetchUser(){
  return 'ellie'
  // 10초 걸린다 치면
}

const user =  fetchUser();
console.log(user)
// 비동기 처리 안 하면 진짜 10초 걸리고 다른 데이터가 표시가 안 됨
  • 지난 시간까지 : 프로미스로 콜백함수 불러서 비동기로 불러옴
function fetchUser(){
  return new Promise((resolve, reject)=>{
  return 'ellie'    
  })
}

const user =  fetchUser();
console.log(user)
>>>Promise { <pending> }
// 팬딩 상태 ; resolve, reject를 꼭 해줘야 결과가 바뀜

근데 이런걸 안 하고 바로 실행 되게 하는 방법이 async임

example

async function fetchUser() {
  return 'ellie'
}

const user = fetchUser();
user.then(console.log);
console.log(user)

2. await

example

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

async function getApple(){
  await delay(3000);
  // 3000 기다줌
  return 'apple'
}

async function getBanana(){
  await delay(3000);
  // 3000 기다려줌
  return 'banana'
}

async function pickFruits(){
  const apple = await getApple();
  const banana = await getBanana();
  return `${apple} + ${banana}`;
}
pickFruits().then(console.log);
  • 자연스럽게 코드 쓰듯이 하는데 실제로는 비동기 처리가 일어나고 있는 것.

문제점

관계 없는 사과와 바나나가 서로 기다리고 있음 -> 병렬 실행

async function pickFruits(){
  const applePromise = getApple();
  const bananaPromise = getBanana();
  // 만들자 마자 실행함
  
  const apple = await applePromise;
  const banana = await bananaPromise;
  // 되는데로 기다렸다가 바로 실행함, 독립적, 병렬적
  return `${apple} + ${banana}`;

근데 이건 너무 코드가 더러움

3. API

1. 개선

function pickAllFruits(){
  return Promise.all([getApple(), getBanana()]).then(fruits=>fruits.join(' + ')
                                                    );
}
pickAllFruits().then(console.log)

2. 누가 먼저..?

function pickOnlyOne(){
  return Promise.race([getApple(), getBanana()]);
}

pickOnlyOne().then(console.log)
  • apple을 빨리 나오게 했음
profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글