Js의 비동기 처리

Javascript는 브라우저를 위한 언어로써 개발되어 싱글스레드를 기반하므로 비동기처리를 독특한 방식으로 수행한다. 자세한 내용은 Js의 비동기 를 참고하도록 하자. 이러한 처리를 손쉽게 하기위해 프로미스가 ES6 기준 표준으로 자리잡았다

프로미스(Promise)

프로미스는 어떠한 작업의 성공, 실패를 담고있다. 이게 무슨소리냐면 프로미스는 그 자체로는 아무것도 하지 않는다는 의미이다. 이러한 상태를 대기(pending)라고 한다.

프로미스는 오직 then()에 의해서 태스크큐에 등록되고 동작을 수행한다. 이 상태를 이행(fullfilled)상태라 한다. 프로미스에 등록된 동작의 종료가 되는 시점에서 해당 결과를 통한 조작을 then()에 등록된 콜백을 통해 실행한다. 즉 메인 스레드의 동작과 관계없이 비동기적으로 수행이 된다.

또한 해당 프로미스가 실패한 동작을 정의할 수 있는데 이를 거부(rejected)상태라 하며 catch()를 통해 등록된 작업을 수행할 수 있다.

프로미스의 사용

let data = ''
setTimeout(() => { data = 'promise' }, 1000)
console.log(data)

위 코드에서 아무것도 출력이 되지 않을 것이라는 것을 js를 좀 다뤄본사람이라면 알 수 있다. 원하는 동작이 data 변수가 변경된 이후의 출력이라고 할 때 프로미스의 활용이 필요해진다. 아래 코드를 보자

let data = ''
new Promise((resolve, reject) => {
  setTimout(() => {
    data = 'promise'
    resolve(data)
  }, 1000)
}).then(res => console.log(res))

해당 코드는 정상적으로 변화한 코드를 출력한다. 프로미스에 등록된 함수를 보면 resolvereject를 받는다. resolve의 호출은 프로미스를 이행(fullfilled)으로 전환하여 then()으로 작업을 넘긴다. reject는 프로미스를 거부(rejected)상태로 넘기며 catch()로 작업을 넘긴다.

위 코드에선 resolve를 1초 후에 실행시키므로 프로미스가 이행상태로 변하는 것이 1초 후이고 그 때 then()에 등록된 작업을 실행한다.

Async / Await

프로미스는 일반적인 동기 스타일과 작성이 다르기 때문에 직관적으로 알아보기 힘들며 비동기 작업의 연속이 진행되면 then()을 무한정으로 등록해야 하므로 코드의 가독성이 좋지 않다. 그에대해 Async / Await 문법이 탄생하였다. 위 코드를 async / await화 하면 아래와 같다.