JS 10-2 비동기처리 - Promise

Seungju Hwang·2021년 1월 28일
0

JavaScript

목록 보기
12/13
post-thumbnail

Intro

비동기처리의 코드 진행 순서를 동기적으로 만들기 위해서 콜백함수를 사용했는데, 콜백함수 뒤에 콜백함수가 붙고 또 콜백함수가 붙는 콜백지옥 이 발생해서 생겨난 개념 Promise !!

약속해요 우리... 다시는 콜백지옥에 빠지지 말기로...


🔵 Promise 개념

A promise is an object that may produce a single value some time in the future
자바스크립트 비동기 처리에 사용되는 객체!

현재에는 당장 얻을 수는 없지만 가까운 미래에는 얻을 수 있는 어떤 데이터에 접근하기 위한 방법을 제공합니다. 당장 얻을 수 없다라는 말은 데이터를 얻는데까지 지연(letency)이 발생하는 경우입니다. I/O나 Network를 통해서 데이터를 얻는 경우가 대표적인데, CPU에 의해서 실행되는 코드 입장에서는 엄청나게 긴 지연 시간으로 여겨지기 때문에 Non-blocking 코드를 지향하는 자바스크립트에서는 비동기 처리가 필수적입니다.

  • Promise 처리 과정

예시1


function findUser(id){
  return new Promise((resolve) => {
    setTimeout(function () {
      console.log('0.1초기다림')
      const user= {
        id:id,
        name:'USER'+id
      }
      resolve(user)
    },100)
  })
}

findUser(1).then(function(res) {
  console.log('user:'+res)
})
//결과
// 0.1초기다림
// user: {id:1,name:USER1}

Promise 객체를 생성하여 리턴하는 findUser 함수.
findUser를 호출하여 그 리턴값을 .then 메서드를 사용하여 결과값을 가지고 실행할 로직을 넘겨줍니다.
💥 콜백함수와의 차이점은, 함수를 호출하면 Promise 타입의 결과값이 리턴되고, 이 결곽밧을 가지고 다음에 수행할 작업을 진행한다는 것입니다.

➡ 그래서 비동기 처리임에도 불구하고 동기처리처럼 직관적으로 코드를 읽을 수 있습니다.

🔵 Promise 생성 방법

Promise는 객체는 new 키워드와 생성자를 통해서 생성할 수 있는데 이 생성자는 함수를 인자로 받습니다. 그리고 이 함수 인자는 resolvereject라는 2개의 함수형 파라미터를 가집니다.

resolve() : 미래 시점에 얻게될 결과를 넘겨주는 정상처리
reject() : 미래 시점에 발생할 예외를 넘겨주는 예외처리

예시1

function devide(numA, numB) {
  return new Promise((resolve, reject) => {
    if (numB === 0) reject(new Error("Unable to devide by 0."))
    else resolve(numA / numB)
  })
}

devide(8, 2)
  .then((result) => console.log("성공:", result))
  .catch((error) => console.log("실패:", error))
//결과
// 성공: 4

devide(8, 0)
  .then((result) => console.log("성공:", result))
  .catch((error) => console.log("실패:", error))
//결과
// 실패: Error: Unable to devide by 0.

then() : 정상적인 인자를 넘긴경우 호출됨
catch() : 비정상적인 인자를 넘긴경우 호출됨


🔵 Promise 사용 방법

실제 개발을 할 땐, Promise를 직접 생성하기보다는 여러 라이브러리의 함수를 호출해서 리턴받은 promise를 then,catch를 통해 사용하는 경우가 더 많습니다.

fetch를 활용한 Promise의 예시 ⭐

⭐ RESTAPI를 호출할 때 사용하는 fetch() 브라우저 내장함수도 호출 결과를 Promise 객체로 리턴합니다. 저는

fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then((response) => console.log("response:", response))
  .catch((error) => console.log("error:", error))

//결과
// response: Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts/1", redirected: false, status: 200, ok: true, …}

Promise의 메서드 체이닝 💥

then(), catch() 메서드는 또다른 Promise 객체를 리턴합니다. 그리고 이 Promise 객체는 인자로 넘긴 콜백함수의 리텃값을 다시 then,catch메서드를 통해 접근할 수 있습니다. 이처럼 연쇄적으로 계속 호출할 수 있습니다.. (어디서 본 거 같네요... 콜백함수...?)

fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then((response) => response.json())
  .then((post) => post.userId)
  .then((userId) => "https://jsonplaceholder.typicode.com/users/" + userId)
  .then((url) => fetch(url))
  .then((response) => response.json())
  .then((user) => console.log("user:", user))
  .catch((error) => console.log("error:", error))

//결과
// user: {id: 1, name: "Leanne Graham", username: "Bret", email: "Sincere@april.biz", address: {…}, …}

💥 then,catch의 인자로 넘긴 콜백함수는 3,4번째 줄 처럼 일반 객체를 리턴하든 또는 5번째 줄처럼 Promise객체를 리턴하든 상관이 없다는 것을 주의해야합니다. 왜냐면 일반 객체를 리턴할 경우, then,catch 메서도는 항상 그 객체를 얻을 수 있는 Promise 객체를 리턴하도록 되어있기 때문입니다!!

➡ 그런데 최근 메서드 체이닝 방식이 async/await 키워드로 대체되고 있습니다... 정말 자주 계속 바뀌네요.. 이래서 개발자가 되려면 끊임없이 공부해야한다고 하나봐요.. 무튼 해야겠죠? 다음 글에서 공부하고 정리할게요.


profile
기록하는 습관은 쉽게 무너지지 않아요.

0개의 댓글