ES6 문법(2) - Promise, async/await

ground4ekd·2020년 11월 19일
0

ECMAScript6 문법

목록 보기
2/4

이전 ES6 문법 1탄에 이어서 비동기 프로그래밍 문법인 Promise, async/await을 공부해보자.

ES5 비동기 프로그래밍

ES6 문법을 사용하기 전까지 자바스크립트에서는 비동기 프로그램이 방식으로 콜백패턴을 많이 사용했다. 콜백패턴은 조금만 중첩돼도 코드가 상당히 복잡해지는 단점이 있다.

function requestData1(callback){
  //...
  callback(data)
}
function requestData2(callback){
  //...
  callback(data)
}

function onSuccess1(data){
  console.log(data)
  requestData2(onSuccess2)
}
function onSuccess2(data){
  console.log(data)
  //...
}

위의 코드는 requestData1를 통해 비동기로 데이터를 받고 난 후에 requestData2로 데이터를 받는 코드이다. 아주 간단한 코드임에도 가독성이 무척 떨어진다. 이러한 단점을 보완하기 위해 Promise, async/await 가 ES6에 추가되었다.

Promise

Promise는 비동기 상태를 값으로 다룰 수 있는 객체이다. 이것을 사용하면 비동기 프로그래밍 코드를 동기 프로그래밍 방식으로 코드를 작성할 수 있다. 먼저 위에서 작성했던 코드에 Promise를 적용해보면 아래와 같다.

requestData1()
  .then(data => {
    console.log(data)
    return requestData2()
  })
  .then(data => {
    console.log(data)
    //...
  })

코드가 짧아질 뿐만 아니라 가독성도 아주 좋아졌다.

Promise 생성

Promise는 뜻 그대로 약속이다. 요청한 처리를 끝내면 알려주겠다는 약속인 것이다.
아래의 코드는 10초뒤에 알려주겠다는 약속을 만드는 코드이다.

const afterTenMin = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve()
  }, 10000)
})

Promise는 세가지 상태로 존재할 수 있는데, 대기중(pending), 이행됨(fulfilled), 거부됨(rejected) 상태가 있다. 처음에 new를 이용하여 Promise 선언시 대기중 상태가 되고, resolve 사용시 이행된 상태의 Promise가, reject 사용시 거부됨 상태의 Promise가 반환된다.

이행됨 상태와 거부됨 상태의 Promise를 아래와 같이 따로 생성할 수 있다.

const rejectedPromise = Promise.reject()
const resolvedPromise = Promise.resolve()

then

then은 Promise가 이행됨(pending), 거부됨(rejected) 상태일 때 처리하는 메서드이다. 위에서 생성한 Promise를 아래와 같이 처리할 수 있다.

const onResolve = () => console.log('Thanks')
const onReject = () => console.log('Whats the matter?!')

afterTenMin()
  .then(onResolve, onReject)  // Thanks

재밌는건 then 은 디폴트로 다시 해당 Promise를 반환한다. 그래서 then을 연속해서 처리할 수 있다.

afterTenMin()
  .then(onResolve, onReject)  // Thanks
  .then(onResolve, onReject)  // Thanks

catch

catch는 거부됨 상태를 따로 처리할 수 있는 메서드이다. then이 이행됨 상태를 처리하고 catch가 거부됨 상태를 처리하면 코드의 가독성이 좋아진다.

Promise.reject()
  .then(data => console.log(data))
  .catch(err => console.error(err))

finally

finally는 Promise가 이행됨 또는 거부됨 상태일 때 호출되는 메서드이다. 상태 상관없이 모두 처리할 때 사용한다.

Promise.resolve()
  .then(() => console.log('ok'))
  .catch(err => console.error(err))
  .finally(() => console.log('finish~~!!!'))

all

다수의 Promise를 병렬로 처리할 때 사용하는 함수이다.

const p1 = () => {
  return new Promise((resolve) => resolve({ data : 1 }))
}
const p2 = () => {
  return new Promise((resolve) => resolve({ data : 2 }))
}

Promise.all([p1(), p2()])
  .then(data => console.log(data))  // [ {data: 1}, {data: 2} ]
  .catch(err => console.error(err))

Promise 들이 모두 이행됨 상태가 되면 데이터를 모두 합친 이행됨 Promise를 반환해주고,
하나라도 거부됨 상태가 되면 거부됨 상태의 Promise를 반환해준다.

race

race는 여러개의 Promise 중 가장 빨리 처리된 Promise를 반환해주는 함수이다.

Promise.race([
  new Promise((_, reject) => setTimeout(reject, 3000)),
  Promise.resolve('goal!!')
])
  .then(data => console.log(data))  // goal!!
  .catch(err => console.error(err))

async / await

async / awiat는 비동기 프로그래밍을 동기 프로그래밍처럼 작성할 수 있도록 함수에 추가된 기능이다. Promise 의 then 을 이용한 체인형식의 방식보다 더 가독성이 좋아진다.

async

async 키워드를 함수에 붙이면 Promise를 반환한다.

async function getData(){
  if(true)
    return 100
  else
    throw new Error('test')
}

getData()
  .then(data => console.log(data))  // 100
  .catch(err => console.error(err))

await

await 키워드는 async 함수 내에서 사용된다. await 키워드 오른쪽에 Promise를 입력하면 해당 Promise가 처리될 때 까지 기다리게 된다.

async function asyncAwaitFunc(){
  const data = await getData()
  console.log('getData 처리되었습니다!')
  const data2 = await getData()
}

글을 마치며

ES6 문법 정보를 찾다보니 Iterator가 자주 나오는데, 다음엔 Iterator를 공부해봐야겠다.

profile
오늘 뭐라도 하나 했다는 것

0개의 댓글