관리 메뉴

꿈꾸는 개발자

프로미스(promise)에 대한 이해 본문

프로그래밍언어/Javascript

프로미스(promise)에 대한 이해

rickysin 2022. 11. 23. 15:41

생활코딩 영상 참고-(1)-then(),catch(),: 

-fetch api를 사용한다(Ajax에 대한 추가적인 내용의 학습이 필요해 보인다!)

  • 해당 사이트의 post에 각각의 글들을 json이란 데이터 타입으로 만든? url을 획득하는 것이다? 
    • 아무튼 url을 통해 서버에 통신하는 것처럼 json 데이터를 fetch할 수 있음!

https://jsonplaceholder.typicode.com/

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. As of Oct 2022, serving ~1.7 billion requests each month.

jsonplaceholder.typicode.com

      //서버와의 통신에 해당한다!
      console.log(1);
      fetch("https://jsonplaceholder.typicode.com/posts")
        .then((response) => response.json())
        .then((data) => console.log(data)); //자동으로 stringify를 해준 json파일이 오는건가?
      //json형태의 파일을 자바스크립트의 data type으로 전환한 것이다!
      console.log(2);

출력값: 1->2-> json data 값(비동기적 처리이기 때문)

  • fetch function의 return 값: response된 object을 return함!(json data값이 아님!)

  • fetch의 호출이 성공하면 then의 callback함수가 실행/실패하면 catch의 callback함수가 실행된다
    • 성공: then(result) =>첫 번째 parameter로 결과값을 받아온다! 
    • 실패하면 catch(reason)의 첫 번째 parameter로 결과값을 받아온다! 
      let data = fetch("https://jsonplaceholder.typicode.com/posts");
      //promise를 return 받음!
      data.then((result) => {
        console.log("result", result);
      });
      data.catch((reason) => {
        console.log("reason", reason);
      });

result의 출력값으로 위의 response object을 return 받게 되어 출력하게 된다!

    let data = fetch("https://jsonplaceholder.typicode.com/posts")
        .then((result) => {
          console.log(result);
        })
        .catch((reason) => {
          console.log(reason);
        });
  • chaining 형태이기 때문에 이런식의 연결이 가능하다=> then의 경우에도 response object을 return 하게 된다!
      let data = fetch("https://jsonplaceholder.typicode.com/posts")
        .then((response) => response.json())
        .then((data) => {
          console.log(data);
        });

response.json의 경우도 promise API에 해당하기 때문에, return을 했을 경우 chaining형태로 then을 붙일 수 있다. 

  • Nesting 방식: then 내부에 then을 작성하는 방식
  • chaining 방식: promise를 return 하기 때문에 뒤에 이어 바로 then을 사용하는 방식(비교적 많은 사용되는 방식이다!)

  • promise API의 전반적인 흐름을 나타내는 그림이다 => 위의 방식을 활용해 흐름의 제어가 가능하다!

생활코딩 영상 참고-(2)-new Promise()

      const p = new Promise((resolve, reject) => {
        resolve(1);
      });
      p.then((result) => {
        console.log(result);
      });
  • 일반적인 Promise 사용법: 
     function promise() {
        return new Promise((resolve, reject) => {
          resolve(2);
        });
      }
      promise().then((result) => {
        console.log(result);
      });
  • 보통 위와 같이 함수 내의 return 값의 형식으로 Promise를 사용한다!
  • Promise nesting 방식:
      function promise1() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(1);
          }, 2000);
        });
      }
      function promise2() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(2);
          }, 2000);
        });
      }
      promise1().then((result) => {
        console.log("promise1", result);
        promise2().then((result) => {
          console.log("promise2", result);
        });
      });

  • 각각 2초 간격으로 console.log가 실행된다! 
    • 하지만 일반적으로 nesting방식보다는 chaining방식을 더 많이 사용한다! 
  • chaining 방식: 
      function promise1() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(1);
          }, 2000);
        });
      }
      function promise2() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(2);
          }, 2000);
        });
      }
      promise1()
        .then((result) => {
          console.log("promise1", result);
          return promise2();
          //then 안에서 promise를 return한다!
        })
        .then((result) => {
          console.log("promise2", result);
          return 1; //이렇게 숫자를 return 하면 다음 then에서는 숫자를  받는다!
        });
  • reject and catch:
  function promise1() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            reject("promise 1 fail");
          }, 2000);
        });
      }
      function promise2() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(2);
          }, 2000);
        });
      }
      promise1()
        .then((result) => {
          console.log("promise1", result);
          return promise2();
          //then 안에서 promise를 return한다!
        })
        .catch((error) => {
          console.log("error", error);
        })
        .then((result) => {
          console.log("promise2", result);
          return 1; //이렇게 숫자를 return 하면 다음 then에서는 숫자를  받는다!
        });

  • reject을 사용하면 실패했을 때의 처리를 try-catch의 방식처럼, then() 뒤에 catch를 사용하면 처리가 된다! catch는 특정 then에 대한 catch가 아닌, 앞에 여러 then이 있을 경우 전체 then에 대한 catch로 작용하게 된다!

혹은 위와 같은 방식으로 Promise().reject()을 통해 뒤 코드의 실행을 막을 수 있다.


코딩엘리 영상 참고: 

  • promise: JS에서 제공하는 비동기처리 prototype
    • 1. state: request한 데이터가 성공적으로 수신 됐는지 상태에 대한 이해!
    • 2. Producer vs Consumer: 데이터를 생성/소비로 분류된다! 
  • new를 이용한 Promise 생성(class이다) => const promise=new Promise(); 클래스 생성자를 이용해서 생성을 하면 된다!  ===>주의점: new Promise()를 하는 순간 executor runs automatically! 

ex

  • executor란 callback함수=> promise 내부에 복잡한 비동기처리를 진행한 후 성공적으로 DATA를 받으면 resolve를 통해 전달을 하고, 실패를 하면 reject을 통해 throw error하면 된다!
  • Producer vs Consumer
    • Resolve/Reject 둘다 사용하기

      //1. producer
      const promise = new Promise((resolve, reject) => {
        //여기에서 데이터를 받고 밑에 then()에 data를 전달하게 된다!
        setTimeout(() => {
          //resolve("ricky");
          reject(new Error("네트워크 연결 불안"));
        }, 2000);
      });

      //2. Consumer, then(), catch(), finally();
      promise
        .then((data) => {
          console.log(data);
        })
        .catch((error) => {
          console.log(error);
        })
        .finally(() => {
          console.log("finally");
        });

resolve callback 함수에 전달한 값을 Consumer인 promise에서 받게 되는 것이다!

  • Promise chaining 연습하기
      //3. Promise chaining:
      const fetchNumber = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(1);
        }, 1000);
      });
      //then 내부에는 주로 callback 함수를 받는 것인가?!?!?
      //주의점: .then의 경우 값을 받을 수도 있고, Promise를 받을 수도 있다!
      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));