본문 바로가기
JavaScript | 자바스크립트

Promise / async / await

by Pig_CoLa 2020. 8. 17.
SMALL

Promise

어떠한 값으로 이행, 거부될 예정인 상태 또는 그 상태가 정해지지 않은 상태를 나타내며

값이 현재 시점에 결정되지 않은채로 작업을 이어나갈때 쓰기 좋은 타입이다.

Promise의 생성

생성하는 방법은 여러가지이다.

  1. Promise.resolve 또는 Promise.reject를 통하여 생성이 가능하다.
  2. 특정한 값이 아닌 함수의 결과 (API를 이용한 미래에 값이 도출되는 경우도 마찬가지이다.)를
    Promise로 만들고 싶을때에는 new Promise(callback)으로 구성이 가능하다.

Promise의 resolve, reject메서드를 통한 생성

Promise.resolve(a)는 a라는 값으로 이행될 Promise를 생성한다.

Promise.reject(a)는 a라는 이유로 거부될 Promise를 생성한다.

let a = Promise.resolve(55);
a.then(data => {conosle.log(data)}); // 55

let b = Promise.reject('잘못된 접근');
b.then(data => {console.log(data)}).catch(err => {throw new Error(err)});
// Uncaught Error: 잘못된 접근

new Promise를 이용한 함수에 대한 Promise생성

new Promise(callback)으로 구성이 가능하며

callback함수의 parameter로 첫번째 자리는 resolve, 두번째 자리는 reject에 각각 대응한다.

callback함수 내에서 resolve 또는 reject를 처음으로 마주할때에 그에 해당하는 상태를 갖는 Promise가 된다.

let a = new Promise((a, b) => {
    if (Math.floor(Math.random() * 2) === 1) {
        a(555);
    } else {
        b('알 수 없는 이유');
    }
})

a
    .then(data => {console.log(data)})
    .then(err => {throw new Error(err)})
// 50%의 확률로 555
// 또는 50%의 확률로 Uncaught Error: 알 수 없는 이유

async / await

async

함수선언시 앞수앞에 사용할 수 있는 키워드로

선언할 함수를 async함수로 만들어준다.

이때에 async함수의 return 되는 값이 Promise라면 그 자체를,

아니라면 그 값으로 이행될 Promise를 돌려준다.

await

async함수 내부에서 사용할 수 있는 키워드로

비동기적 실행의 결과값을 기다린 후 이행될 값을 반환한다.

이때에 비동기적으로 실행한 무언가의 return값은 Promise type이어야만

의도한 대로 작동한다.

(비동기적 실행이 아니더라도 일반적인 Promise가 와도 된다. 그 값이 이행될 값을 반환한다.)


기존 Promise의 비동기적 실행에 의해 돌려받은 값에 따라 분기를 나누어야 한다면

아래와 같을 것 이다.

// 호출할 때 마다 1초후에 어떠한 값으로 가지는 Promise를 반환하는 함수이다.
function hi() {
  return new Promise((a, b) => {
    setTimeout(() => {
      if (Math.floor(Math.random() * 2) === 1) {
        a(555);
      } else {
        a(999);
      }
    }, 1000);
  });
}

// 이 Promise가 이행할 값에 따라 어떠한 분기를 만들기 위해선 .then을 활용해야 한다.
hi()
  .then(data => {
    console.log(data);
    if (data === 555) {
      return '오백오십오'
    } else if (data === 999) {
      return '구백구십구'
    }
  })
  .then(data => {
    console.log(data);
  })
// (1초후에 50%확률로)
// 555
// 오백오십오

// (또는 나머지 50%확률로)
// 999
// 구백구십구

물론 분기에 따른 행동이 완전히 상이하다면 then에 then에 then... 꼬리를 물게 되었을 것이다.


이와 같은 문제는 callback hell 때문에 가독성이 떨어져 Promise를 도입한 것이지만

이역시 비동기의 완료를 기다리고, 완료가 이루어지면 또다른 비동기를 호출하거나,

위와같이 이행될 값에 따른 분기를 만들기에는 Promise chain hell이 일어난다.


하지만 이를 async / await 을 통해 작성한다면 어떻게 될까?

async function hi() {
  let data = await new Promise((a, b) => {
    setTimeout(() => {
      if (Math.floor(Math.random() * 2) === 1) {
        a(555);
      } else {
        a(999);
      }
    }, 1000);
  });

    console.log(data);

  data = await new Promise((a, b) => {
    if (data === 555) {
      a('오백오십오');
    } else if (data === 999) {
      a('구백구십구');
    }
  })

  console.log(data)
}

hi()
// (1초후에 50%확률로)
// 555
// 오백오십오

// (또는 나머지 50%확률로)
// 999
// 구백구십구

이처럼 분명 비동기적 실행의 동기적 흐름에 대하여 매우 읽고 쓰기 편하게 작성 할 수 있게 된다.

코드를 읽기 편하게 작성하는것의 중요성은 이미 알고 있을것이다.


전에는 잘 짜여진 로직에 따라 정상적으로 실행된다면 그만이었을지 모르지만

협업이 중요시되고 있는 현재에는 '성능'만큼이나 중요한 것이 '가독성'이다.

물론 성능을 포기하고 가독성을 택하는 일은 드물겠지만 동일한 성능에서 가독성이 더 좋은데 굳이 차용하지 않을 이유가 무엇인가.


만일 이 글을 읽는 당신이 평생 혼자서 작업하고 혼자만의 코드를 세상에 공유없이 혼자만 사용한다면전혀 주의할 필요가 없을 것이다.

하지만 그렇지 않다면 내가 설명할 시간, 코드를 보는 사람이 이해할 시간 등등
자원소모(시간은 가장 중요한 자원중 하나다)가 적을 수록 효율적인 process가 갖춰질 것이다.

LIST

'JavaScript | 자바스크립트' 카테고리의 다른 글

JavaScript - class 다중상속  (0) 2020.07.29
OOP - 객체지향 / 상속  (0) 2020.07.29
복잡도 - 시간복잡도  (0) 2020.07.19
재귀호출  (0) 2020.07.18
함수의 메서드 - call, apply, bind  (2) 2020.07.17

댓글