ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 개발공부 31일차 [노데미 자바스크립트 응용]
    개인공부 2023. 2. 25. 00:06

    오늘 진짜 개발공부 시작하고 역대로 현타오는 날이였다..

    분명 어제도 너무 어려웠고 새로운게 수두룩빽빽이였는데 오늘은 뭔가 어제보다 배운 다양성은 적긴한데 

    promise가 그냥 날 미궁으로 이끌었고 현타를 씨게맞아버렸다.

    지금까지 배운 자바스크립트는 정말 적었었고 기본이라는 promise마저 천천히 듣고 이해하려하고 외워보려했지만 

    제대로 알지 못했다. 

     

    자바스크립트 응용

    spread

    중복된 프로퍼티를 새로운 객체에 펼치는 역할.

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

    배열원소들을 순서대로 펼칠 수 도있음.

    const noTopingCookis = ['촉촉한쿠키', '안촉촉한쿠키']
    const topingCookis = ['바나나쿠키', '블루베리쿠키', '딸기쿠기', '초코칩쿠키']
    
    const allCookies = [...noTopingCookis, "함정쿠키", ...topingCookis]
    console.log(allCookies)
    //['촉촉한쿠키', '안촉촉한쿠키', '함정쿠키', '바나나쿠키', '블루베리쿠키', '딸기쿠기', '초코칩쿠키']

     

    동기 & 비동기

    function taskA(){
      console.log("TASK A")
    }
    function taskB(){
      console.log("TASK B")
    }
    function taskC(){
      console.log("TASK C")
    }
    
    //호출하는 순서
    taskA()
    taskB()
    taskC()

    동기 방식의 처리

    자바스크립트는 코드가 작성된 순서대로 작업을 처리함

    이전 작업이 진행 중 일 때는 다음 작업을 수행하지 않고 기다림

    먼저 작성된 코드를 먼저 다 실행하고 나서 뒤에 작성된 코드를 실행한다.

     

    동기처리 방식의 문제점

    동기적 처리의 단점은 하나의 작업이 너무 오래 걸리게 될 시, 모든 작업이 오래 걸리는 하나의 작업이 종료되기 전 까지 올 스탑 되기 때문에 전반적인 흐름이 느려진다.

    웹사이트에서 버튼 하나하나마다 30초씩 걸리면 속 터진다.

     

    비동기 작업

    싱글 쓰레드 방식을 이용하면서, 동기적 작업의 단점을 극복하기 위해 여래 개의 작업을 동시에 실행시킴

    즉, 먼저 작성된 코드의 결과를 기다리지 않고 다음 코드를 바로 실행함.

    하나하나 작업들이 정상적으로 끝났는지 확인하려면 비동기방식으로 실행된 함수에 콜백함수를 붙쳐서 끝났는지 확인하면 된다.

    function taskA(){
      setTimeout(()=>{console.log("A TASK END")},2000)
      //2초뒤에 첫번째 인자의 콜백함수를 실행시키게 됨
    }
    
    taskA();
    console.log("코드 끝")
    
    // 결과값
    // 코드 끝 
    // A TASK END

    이처럼 비동기 함수는 바로 실행되는 “코드 끝” 이 먼저 출력되고

    2초뒤에 “A TASK END”가 출력된다.

    콜백함수 참고 영상 : https://www.youtube.com/watch?v=wvEYG6ydAGg

    function taskA(a, b, cb) {
      setTimeout(() => {
        const res = a + b
        cb(res) //지역함수
      }, 3000)
      //3초뒤에 첫번째 인자의 콜백함수를 실행시키게 됨
    }
    
    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("코드 끝")
    
    // 코드 끝
    //B TASK RESULT :  14
    //C TASK RESULT :  -14
    // A TASK RESULT :  7

    바로 실행되는 “코드 끝”이 출력이 되고

    1초뒤에 실행되는 taskB의값

    2초뒤에 실행되는 taskC의값

    3초뒤에 실행되는 taskA의값이 차례대로 출력된다.

    function taskA(a, b, cb) {
      setTimeout(() => {
        const res = a + b
        cb(res) //지역함수
      }, 3000)
      //3초뒤에 첫번째 인자의 콜백함수를 실행시키게 됨
    }
    
    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("코드 끝")
    
    // 코드 끝
    // A RESULT :  9
    // B RESULT :  18
    // C RESULT :  -18

    비동기처리의 결과를 또 다른 비동기처리의 값으로 처리 할 수있다.

    다만 가독성이 떨어지고 계속 콜백을 쓸 경우 콜백 지옥이 나타난다.

    콜백지옥에서 구원해줄 promise가 있다.

     

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

    pending

    비동기작업이 진행중이거나 시작할 수 도없는 문제가 발생함을 의미

    Fulfilled

    비동기작업이 완료된 상태

    Rejected

    비동기작업이 어떠한 이유로 실패한 상태

    function isPositive(number, resolve, reject) {
      setTimeout(() => {
        if (typeof number === 'number') {
          //성공 ->resolve
          resolve(number >= 0 ? "양수" : "음수")
        } else {
          //실패 -reject
          reject("주어진 값이 숫자형 값이 아닙니다");
        }
      }, 2000)
    }
    
    isPositive(10,(res)=>{
      console.log("성공적으로 수행됨 : ",res)
    },(err)=>{
      console.log("실패 하였음 : ",err)
    })
    //성공적으로 수행됨 :  양수
    isPositive([],(res)=>{
      console.log("성공적으로 수행됨 : ",res)
    },(err)=>{
      console.log("실패 하였음 : ",err)
    }) //실패 하였음 :  주어진 값이 숫자형 값이 아닙니다

    promise

    어떤함수가 프로미스를 반환한다는것은 그 함수는 비동기작업을 하고 그작업의 결과를 프로미스의 객체로 반환받아서 사용할 수 있는 함수

    function isPositiveP(number) {
      const executor = (resolve, reject) => { //실행자 비동기작업을 실질적으로 수행하는 함수 
        setTimeout(() => {
          if (typeof number === 'number') {
            //성공 ->resolve
            resolve(number >= 0 ? "양수" : "음수")
          } else {
            //실패 -reject
            reject("주어진 값이 숫자형 값이 아닙니다");
          }
        }, 2000)
      }
      const asyncTask = new Promise(executor)
      return asyncTask
    }
    const res = isPositiveP([]);
    
    res
      .then((res) => {
      console.log("작업성공 : ", res)
      })
      .catch((err) => {
        console.log("작업실패 : ", err)
      }) 
    
    //작업실패 :  주어진 값이 숫자형 값이 아닙니다
    function taskA(a, b) {
      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) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const res = a * -1;
          resolve(res)
        }, 2000)
      })
    }
    
    taskA(2, 4).then((a_res) => {
      console.log("A RESULT : ", a_res);
      return taskB(a_res);
    }).then((b_res) => {
      console.log("B RESULT : ", b_res)
      return taskC(b_res);
    }).then((c_res) => {
      console.log("C RESULT : ", c_res)
    })
    
    // 코드 끝
    // A RESULT :  6
    // B RESULT :  12
    // C RESULT :  -12
    
    
    // taskA(3, 4, (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("코드 끝")

    promise를 이용해서 이전에 썼던 콜백지옥을 벗어날 수 있다.

     

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

    async

    async가 붙은 함수가 promise를 반환하게 함.

    함수 앞에 async를 넣어주면 helloAsync가 프로미스를 반환하는걸 알 수 있음.

    //async
    
    function hello(){
      return 'hello'
    }
    
    async function helloAsync(){
      return 'hello Async'
    }
    
    console.log(hello())
    // hello
    console.log(helloAsync())
    // Promise {<fulfilled>: 'hello Async'}

    promise객체를 그냥 출력하면 promise자체를 출력하게됨

    //async
    
    function hello(){
      return 'hello'
    }
    
    async function helloAsync(){
      return 'hello Async'
    }
    
    helloAsync().then((res) => {
      console.log(res)
    })
    // hello Async

    helloAsync함수를 .then을 이용해서 출력을 시키면 res에 리턴값이 전달이 되어서 출력이 된다.

     

    await

    async가 붙은 함수에만 사용 할 수 있다.

    //await
    
    function delay (ms){
      //delay함수를 호출할때 ms시간을 넣어주면 넣어준 시간 후에 함수가 호출이 된다.
      return new Promise((resolve) => {
        setTimeout(resolve,ms)
        //setTimeout함수안에 resolve를 호출하는것말고는 없으면 콜백함수 자체를 resolve로 해도 무방하다.
        })
      }
    
    
    async function helloAsync(){
      await delay(3000);
      return "hello async"
    }
    //아래 함수랑 동일하게 작동한다.
    
    // async function helloAsync(){
    //   return delay(3000).then(() => {
    //     return 'hello Async'
    //   }) 
    // }
    
    async function main(){
      const res = await helloAsync()
      console.log(res)
    }
    
    main();
    // hello Async

    API & fetch

    API(Application Programming Interface)

    응용 프로그램 프로그래밍 인터페이스

     

    응용 프로그램에서 사용할 수 있도록,

    운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

    주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다.

    1. request 유저가 웹브라우저에서 서버에 데이터요청
    2. query 서버가 DB에 원하는걸 찾는다.
    3. query result 데이터베이스의 값을 꺼내온다.
    4. response 서버가 요청받은 데이터를 유저에게 다시 보여준다.

    https://jsonplaceholder.typicode.com/

    개발자들을 위해서 아무조건없이 무료로 범위데이터를 응답해주는 서비스를 해준다.

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

    결국 난 프로미스를 당장 포기했다.. 리엑트에도 자주 사용된다고 하니까 리엑트 공부하다보면 조금은 익숙해지지 않을까 싶다..😭

    그래도 .then은 이전에는 그냥 웹개발종합반 강의들으면서 복붙해서 쓰다보니까 왜쓰는지 몰랐는데 프로미스를 불러오기위해 .then을 써야한다는건 알아버렸다 하나라도 얻어간게 어딘가 싶다.

     

Designed by Tistory.