JavaScript

[JavaScript]자바스크립트 고수 되기 02 - Promise & async,await

무서운승태 2023. 11. 10. 19:09
728x90

비동기 프로그래밍에서 동기적 표현이 왜 필요한가

현대 애플리케이션에서는 비동기 프로그래밍은 선택이 아닌 필수가 되었다. 여기서 동기와 비동기에 대하여 아주 간단하게 언급하자면 다음과 같다.

 

https://learnjs.vlpt.us/async/

  1. 동기 => 앞선 동작이 끝나야 다음 동작을 수행할수 있다.
  2. 비동기 => 앞선 동작이 끝나지 않아도 다음 동작을 수행한다.

동기적 동작을 살펴보면 1번동작이 끝나야 2번 동작을 수행하고 그다음 3번, 4번으로 동작하게 된다. 1번 동작이 얼마나 걸리던 뒤에 동작은 1번 동작이 종료할 때까지 작동하지 않는다.

 

비동기 동작은 모든 동작을 받아서 한꺼번에 처리한다. 그러나 일의 종료순서를 보장하지는 않는다.

 

그러면 우리가 앞으로 배울 Promise나 async await같은걸 왜 사용을 할까??

바로 "비동기 동작의 동기적 표현을 위함" 이다. 이 문장을 본 대부분의 사람들은 이 생각이 들것이다.

"모든 동작을 받아서 한꺼번에 처리하는것이 비동기라고 했는데 왜 비동기에 순차적으로 처리하는 동기적 표현이 필요하다는 거지??"

다음은 이해를 돕기 위한 아주 간단한 예이다.

유저정보를 가져오는 getUser함수가 있고 그 정보를 바탕으로 상세정보를 검색하는 getDeatil함수가 있다. getUser함수는 3초 정도 걸리는 동작이고 getDeatil은 5초 정도 걸린다고 가정하자.(두 동작다 비동기 동작으로 가정한다)

실행 결과이다. 일반적으로 우리가 생각하는 동작 그대로 작동한다. 그러나 이 코드는 언제나 동일한 결과를 준다는 보장이 있을까??

대답은 아니요 이다. 위 코드 상태라면 만약 getUser의 동작이 네트워크 사정에 때문에 평소보다 10초 늦는다면 getUser 정보 없이

getDetail 상세화면을 조회하게 된다. 이것은 치명적이며 애플리케이션이 즉시 종료될 수도 있다.(실제로 겪었었다.)

우리는 비동기 동작의 순서를 정해줌으로써 우리가 원하는 결과를 얻기 위해 "비동기 동작의 동기적 표현"이 필요한 것이다.

 

비동기 동작의 동기적 표현 방법

콜백함수

  • 비동기 동작에 콜백함수를 주어서 순서를 정해준다.
  • 그러나 동작이 많을수록 depth가 많아지는 콜백지옥으로 빠질 수 있다.
  • 가독성과 유지보수성을 매우 해치기에 절대로 사용하면 안 된다.

Promise

  • 비동기 함수를 호출할 때 성공과, 실패에 대한 처리를 정의할 수 있는 객체
  • 객체 내 콜백함수를 받는데 인자값은 resolve(성공)와 reject(실패)를 받는다

  • resolve(성공) 시 인자값으로 실행결과에 대하여 반환할 수 있다. (then 키워드로 그다음 동작을 이어할 수 있다.)
    • 성공 시 resolve를 실행히시키고 인자가 있으면 넘겨주면 된다
  • reject(실패) 시 실패에 대한 error를 반환할 수 있다. (catch 키워드로 오류에 대한 처리를 할 수 있다.)
    • 실패 시 reject를 실행시키고 error를 넘겨줄 수 있다.

promise를 이용하여 앞선 예제를 바꿔 보았다.

이로써 검색의 순서를 보장할 수 있게 되었다.

 

Promise의 3가지 상태

  • Pending(대기)
    • 처리가 완료되지 않은 상태 (대기)
  • Fulfiled(이행)
    • 처리가 성공되어 이행 상태가 된다. ⇒ 완료 then으로 이후 처리가능
    • then에서 return을 할시 promise로 감싸서 리턴된다.
    • 그래서 추가적으로 then으로 후속처리(프로미스 체이닝)가 가능하다
  • Reject(실패)
    • 처리가 실패한 상태 ⇒ catch로 error에 대한 처리

 

async await

  • async가 붙은 함수는 항상 promise를 반환한다.
  • promise가 아닌 값을 반환해도 이행 상태의 프로미스를 감싸서 반환한다.
  • await가 붙은 프로미스는 해당 동작이 종료될 때까지 진행되지 않고 기다린다.
  • await는 async함수 내에서만 작동된다!!

위 구문이 아주 간단하고 직관적으로 변했다.

결과도 정상적으로 동작한다. 앞으로 프로젝트에서 api요청에 대해 많이 다룰 거 같다. 그때 잘 사용할 수 있도록 위 개념을 잘 숙지하고 있어야 된다.