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개의 댓글

관련 채용 정보