본문 바로가기

자바스크립트

[Javascript] - async와 await

 

asyc와 await

 

-  async와 await라는 특별한 문법을 사용하면 프로미스를 좀 더 편하게 사용할 수 있다.

 

async 함수

 

- async 키워드는 function 앞에 위치한다.

 

 

- function 앞에서 async를 붙이면 해당 함수는 항상 프로미스를 반환한다.

- 프로미스가 아닌 값을 반환하더라도 이행 상태의 프라미스로 값을 감싸 이행된 프라미스가 반환되도록 한다

- 예제의 6번째 줄처럼 후속 처리 메서드 then을 통해서 result 값인 1을 호출할 수 있다.

 

 

- 위 예제처럼 명시적으로 프라미스를 반환하는 것도 가능하다. 결과는 동일하다

 

await

- await키워느는 async 함수 내에서만 동작한다.

 

 

- 기본적인 문법은 위 예제와 같다.

- 자바스크립트는 await키워드를 만나면 프라미스가 처리될 때까지 기다린다 결과는 그 이후 반환된다.

 

 

- 위 예제는 1초 후 이행되는 프라미스를 예시로 사용한 예제이다.

- 위 예제에서 f() 함수를 호출하면 함수 본문이 실행되는 도중에 8번째 줄에서 실행이 잠시 중단되었다가 프라미스가 처리되면 실행이 재개된다.

- 이때 프라미스 객체의 result 값이 변수 result에 할당된다 따라서 위 예제는 함수를 호출하면 1초 뒤에 완료가 호출된다.

 

- await은 말 그대로 프라미스가 처리될때까지 함수 실행을 기다리게 만든다 즉 프라미스가 처리되면 그 결과와 함께 실행이 재개된다.

- 프라미스가 처리되길 기다리는 동안에는 엔진이 다른일 등을 처리 할 수 있기 때문에 CPU리소스가 낭비되지는 않는다.

- await 는 promise.then 보다 좀 더 세련되게 프라미스의 result값을 얻을 수 있는 문법이며 가독성도 좋다.

 

 

일반 함수엔 await을 사용할 수 없다.

 

 

- 위 예제처럼 function 앞에 async를 붙이지 않으면 Syntax Error가 발생한다 위에서 말했다 싶이 await는 async함수에서만 동작한다.

 

await는 최상위 레벨 코드에서 작동하지 않는다.

 

 

-   await는 최상위 레벨 코드에서 작동하지 않는다 즉 위 예제는 작동하지 않는다.

 

 

- 하지만 즉시 실행 함수를 이용해서 코드를 감싸면 최상위 레벨 코드에서도 await을 사용할 수 있다.

 

async 클래스 매서드

- 메서드 이름 앞에 async를 추가하면 async 클래스 메서드를 선언할 수 있다.

 

 

- async 메서드와 async 함수는 프라미스를 반환하고 await을 사용할 수 있다는 점에서 동일하다.

 

에러 핸들링

 

- 프라미스가 정상적으로 이행되면 await promise는 프라미스 객체의 result에 저장된 값을 반환한다.

- 반면 프라미스가 거부되면 마치 throw문을 작성한 것처럼 에러가 던져진다. 예제로 확인해보자

 

 

- 위코드와 아래 코드는 동일하다.

 

- 따라서 await 가 던진 에러는 throw가 던진 에러를 잡을 때 처럼  try...catch를 사용해 잡을 수 있다.

 

- async/await 문법은 try...catch문을 이용해 에러를 잡기 때문에 일반적인 try...catch 문처럼 에러가 발생하면 에러 흐름이 catch블록으로 넘어간다.

 

 

- 만약 try...catch문이 없다면 async 함수인 f()는 프로미스 거부 상태가 되며  catch()를 이용해 거부된 프라미스를 처리할 수 있다.

 

async/await과 promise.then/catch

 

- async/await을 사용하면 await가 대기를 처리해주기 때문에 사실상 promise의 then이 거의 필요하지 않는다 여기에 더하여 catch를 통해 에러를 잡는 것도 try...catch를 사용할 수 있다는 장점이 있다.

 

- 항상 그런 것은 아니지만 promise.then을 사용하는 것보다 async/await을 사용하는 것이 대개 더 편리하다.

- 하지만 자바스크립트 문법적 제약 때문에 async는 함수 바깥의 최상위 레벨 코드에선 await을 사용할 수 없다 그렇기 때문에 관행처럼 .then/catch를 추가해 최종 결과나 처리되지 못한 에러를 다룬다.

 

async/await과 Promise.all

 

- 여러개의 프라미스가 모두 처리되길 기다려야 하는 상황이라면 이 프라미스들을 Promise.all로 감싸고 여기에 await을 붙여 사용할 수 있다