본문 바로가기
IT 개발

[드림코딩]자바스크립트 기초 정리 ⑩ 비동기의 꽃 JavaScript async 와 await 그리고 유용한 Promise APIs

by gorokeya 2021. 6. 25.

async await ?

promise를 조금 더 간결하고 동기적으로 실행되는 것처럼 보이게 만들어준다

프로미스 체이닝(. then. then. then... catch)을 계속하면 코드가 난잡해질 수 있는데 여기에 간편한 API로

async await 사용하면 동기식으로 코드를 순서대로 작성하는 것처럼 간편하게 작성할 수 있도록 도와준다.

즉 깔끔하게 프로미스 사용이 가능하다!

 

syntactic sugar : 기존에 존재하던 것 위에 간편하게 사용할 수 있도록 API를 이용하는 것 (ex. class)

 

 

여기 프로미스에서 resolve, reject 아무것도 호출하지 않았기 때문에

현재 프로미스 상태는 pending으로 남아있다 (결괏값도 없음)

꼭 resolve, reject로 완료를 해줘야 한다.

 

 

프로미스에 resolve를 호출했더니 이제 콘솔 창에서

프로미스의 결괏값이 변한 걸 볼 수 있다

 

 

그렇다면 async는 어떻게 사용할까?

함수 앞에 async를 붙여주면 프로미스 생략이 가능하다

프로미스를 생략해도 자동적으로 함수 안의 코드 블록들이 프로미스로 변환된다.

 

그렇다면 await은?

await은 async가 붙은 함수 안에서만 사용이 가능하다

 

 

여기서 delay함수는 정해진 ms가 지나면 resolve 호출하는 프로미스를 리턴함

밑에선 3초를 전달했기 때문에 3초 지나면 리졸브 호출하는 함수가 됨

여기서 await을 사용하여 딜레이가 끝날 때까지 기다려준다.

3초 뒤에 사과를 리턴하는 프로미스가 만들어진다.

그리고 바나나는 다시 프로미스를 만들어서 얘도 3초 뒤에 바나나를 리턴해준다

 

 

만약 then으로 작성하면 밑의 코드처럼 되는데

위에 await처럼 동기적으로 보이게 만들면 더 쉽게 이해가 가능하다

 

 

사과와 바나나를 가져오는 함수를 만들고 먼저 사과받아오고 그다음에 바나나를 받아오고

마지막으로 사과, 바나나를 호출한다

근데 모양이 콜백 지옥같이 생겼다 (!)

프로미스도 너무 중첩적으로 체이닝 하면 콜백 지옥과 비슷한 문제점이 생기는데

이걸 async로 바꾼다면?

 

 

한눈에 알아보기 쉽게 변경이 가능하다

하지만 문제점이 있는 부분은 await으로 인해 기다리는데 사과와 바나나는 서로 연관이 되어있지 않아서

사실 전혀 기다릴 필요가 없다

 

 

첫 번째 해결방법은

각각 프로미스를 만드는 것. 왜냐면 프로미스는 만들자마자 실행이 되기 때문이다

이렇게 하면 1초 만에 병렬적으로 실행이 된다

하지만 사과 다운로드하는데 바나나 필요 없고, 바나나 다운로드할 때 사과 필요 없으면

병렬적으로 기능 수행 가능 경우엔 저렇게 코드 작성을 하지 않는다

 

 

이건 프로미스 배열을 전달하게 되면 모든 프로미스를 받을 때까지 병렬적으로 모아준다

위에서 apple, banana같이 다 받아진 배열이 다시 전달되고, 배열을 스트링으로 묶을 수 있는 건 join

콘솔 창을 보면 두 번 출력되어있다 (위에 출력하는 다른 코드가 있어서 겹침)

 

 

어떤 것이든 상관없고 먼저 얻어지는 첫 번째 과일만 받아올 땐? (사과는 2초, 바나나는 1초라는 가정하에)

 

 

프로미스의 race는 배열에 저장된 프로미스 중 가장 먼저 값을 리턴하는 아이만 전달된다

콘솔 창을 보면 바나나가 먼저 호출되어서 콘솔 창에 입력되는 걸 확인 가능하다

 

 

Ref

https://www.youtube.com/watch?v=aoQSOZfz3vQ&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=13 

반응형