Promise 조합 + Async 이해하기

CCY·2020년 8월 14일
0

Javascript 모음

목록 보기
11/11
post-thumbnail

Promise를 써야 하는 이유

하나의 비동기 계산이 다른 비동기 계산의 결과에 의해 처리되어야 하는 경우가 많다.

이전에는 Callback 패턴을 통해 비동기 처리를 하였는데, 중첩된 비동기 코드들을 처리하다 보면 콜백들이 너무 많아서 Callback hell 이라고도 많이 불렀다.

이러한 비동기 코드들의 조합을 Promise 기반으로 작성하면 명료한 코드를 작성 할 수 있고 예외 처리를 손쉽게 할수 있게 되었다.

Promise(.then) 메소드에서 새로운 비동기 코드를 실행하는 Promise를 반환 할 수 있는데 다음 then 메소드는 새롭게 만들어진 Promise 코드가 이행되기 전까지 호출되지 않는다.

function doJob(name, person) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (person.stamina > 50) {
        resolve({
          result: `${name} success`,
          loss: 30,
        })
      } else {
        reject(new Error(`${name} failed`))
      }
    }, 1000)
  })
}

const john = { stamina: 100 }

doJob("work", john)
  .then((value) => {
    console.log(value.result)
    john.stamina -= value.loss
    return doJob("study", john)
  })
  .then((value) => {
    console.log(value.result)
    john.stamina -= value.loss
    return doJob("work", john)
  })
  .then((value) => {
    console.log(value.result)
    john.stamina -= value.loss
    return doJob("study", john)
  })
  .catch((e) => console.error(e))
  1. 이름에 일을 수행하는 약속을 생성하는 doJob 함수를 정의합니다.
    스테미나를 속성으로 갖는 객체를 매개변수로 전달받아 스테미나가 50보다 많으면 약속이 이행된다.

이행 결과로 스테미나를 차감할 값을 포함하는 객체를 전달하고, 50 이하면 약속이 거부된다.

2.work 이름의 약속(Promise)를 생성하고 , 전달된 인자에 100의 스테미나를 부여합니다.

  1. .then 메소드에 전달한 콜백함수를 study 라는 약속을 반환하게 한다.
    그다음에 다시 .then 메소드로 work 약속을 이행하게 하고 마지막으로 study 함수를 다시 불러봅니다.

위에서 보이듯이 Promise (pending) 으로 약속을 실행 대기중이다가 성공,성공, 실패가 뜸니다.
이것은 위에서 stamina가 약속이 실행될때마다 -30이 되는것이라 100에서 -30 ,-30 을 해서 결국에 50이하 인 40의 stamina가 있어 더이상의 Promise가 이행되지 않은것입니다.

그럼 Async 는 무엇인가?

ES08에서 소개된 async 는 함수안의 await 구문과 함께 비동기 작업을 제어합니다.
await 키워드는 반드시 async 함수안에서만 유효합니다.

async 함수의 동작 방식은 다음과 같습니다, 처음 async 함수가 호출되어 await 키워드가 있는 비동기작업(Promise 객체)이 실행되면, 해당 비동기 함수는 이벤트 루프를 통해 비동기 작업을 처리한다.

그동안 async 함수는 이러한 비동기 작업이 완료될 때가지 일시 중지 상태로 비동기 작업 (Promise 객체)의 해결 (resolve) 을 기다린다. 이 작업이 완료 되면 async 함수가 다시 실행되고 함수 결과를 반환한다.

async 함수를 선언하는 방법에는 async 함수 선언문(async function) 과 표현식(async function expression) 이 있다.

위에 Promise 조합하기 예제 코드를 Async 함수로 바꿔 보겠다.


function doJob(name, person) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (person.stamina > 50) {
        person.stamina -= 30
        resolve({
          result: `${name} success`,
        })
      } else {
        reject(new Error(`${name} failed`))
      }
    }, 1000)
  })
}

const fran = { stamina: 100 }

const execute = async function () {
  try {
    let value = await doJob("work", fran)
    console.log(value.result)
    value = await doJob("study", fran)
    console.log(value.result)
    value = await doJob("work", fran)
    console.log(value.result)
  } catch (e) {
    console.log(e)
  }
}

execute()

위에서 Promise 조합으로 .then 을 사용하여 3번 할 작업을 aync function으로 try 안에 3가지를 넣어 제어 할 수 있게 되고, catch 로 에러를 잡을 수 있다는것이 확인됬다.

더욱 깔금한 코드이면서 간단하게 Promise 를 제어 할 수 있어 주로 사용된다.

profile
✍️ 기록을 습관화 하자 ✍️ 나는 할 수 있다, 나는 개발자가 될거다 💪🙌😎

0개의 댓글