JavaScript/ES6

[ES6]Promise 어려워서 싫으면 async/await을 사용합시다

MoZZANG 2022. 8. 30. 20:05

Promise가 어렵다면 그보다 훨씬 쉽게 쓸 수 있는 ES8 문법이 있습니다.

async, await이라는 키워드인데 각각 Promise와 then을 매우 쉽게 만들어주는 문법입니다. 

같이 알아봅시다. 

 

 

 

 

async 키워드를 쓰면 Promise 오브젝트가 절로 생성됩니다.

 

말그대로입니다. new Promise() 어쩌구 하실 필요가 없습니다.

근데 이 키워드는 function 선언 앞에만 붙일 수 있습니다.  

 

그럼 이 함수 자체가 Promise가 되어버립니다.

그래서 이 함수를 실행할 때 뒤에 then을 붙일 수 있습니다. Promise니까요. 

(함수를 실행하면 그 자리에 Promise 인스턴스 (new Promise() 로 만든 오브젝트)가 남습니다. )

 

 

그럼 이제 Promise 만들 때 했던거 처럼 then을 붙여서 더하기() 함수가 성공한 뒤에 뭔가를 실행시킬 수 있습니다.

(훨씬 쉽네요 진작에 이렇게 만들것이지)

 

 

 

함수안에서 연산한 결과를 then 안에서 사용하고 싶다면 

이렇게하시면 됩니다.

return 오른쪽에 결과를 적어주시면 됩니다. 그럼 then함수까지 전해집니다.

 

 

 

 

then() 함수가 귀찮다면 await 키워드를 쓸 수 있습니다.

async 키워드를 쓴 함수 안에서는 await을 사용가능합니다.

await은 그냥 프로미스.then() 대체품으로 생각하시면 됩니다. 

하지만 then보다 훨씬 문법이 간단합니다. 

 

 

새로운 예제를 만들어봅시다.

어떤 function 안에서 어려운 연산을 실행한 뒤에 성공/실패를 판정해주는 Promise를 만들고 싶습니다. 

그럼 어떻게 합니까.

 

많이 했던 패턴대로 이렇게하시면 됩니다.

(혹은 Promise 만들기 귀찮으면 어려운연산을 함수로 만든 후 async를 쓰시면 됩니다)

 

그럼 이제 어려운연산.then() 이렇게 성공시 특정 코드를 실행할 수 있습니다. 

근데 .then()이게 너무 복잡해서 보기 싫으시면 

await이라는 키워드를 이용가능합니다. 

 

 

어려운연산.then() 과 매우 유사한 문법입니다.

정확한 뜻은 어려운연산 Promise를 기다린 다음에 완료되면 결과를 '결과'라는 변수에 담아주세요 

입니다. 

 

 

연산 결과를 출력하거나 그러고 싶다면

성공 함수에 파라미터를 담아주시면 됩니다.

 

성공()함수 안에 있던 2라는 파라미터는

var 결과라는 변수에 저장됩니다. 

그럼 Promise의 연산 결과를 출력해볼 수도 있겠네요. 

 

 

(주의) 비동기식처리되는 코드를 담는다면 await 기다리는 동안 브라우저가 잠깐 멈출 수 있습니다.

 

 

 

 

 

await은 실패하면 에러가 나고 코드가 멈춥니다.

 

Promise가 실패하는 하단 코드를 실행해봅시다.

 

어려운연산이라는 Promise가 실패할 경우

await 어려운연산이라는 코드는 에러가 나고 코드실행을 멈춥니다.

그럼 await 하단에 있는 코드들은 더 이상 실행이 되지 않겠죠.

 

 

그래서 Promise가 실패할 경우

코드실행을 멈추고 싶지 않으면 약간 특별한 방법이 필요합니다. 

try catch라는 자바스크립트 문법인데,

try {} 안의 코드가 에러가 나고 멈출 경우

대신 catch {} 내부의 코드를 실행해줍니다. 

 

이렇게 에러처리를 하실 수 있습니다. 더 복잡하니까 그냥 then() 이런거 쓰셈 

어려운연산이라는 Promise가 실패()가 안날거라고 자신하면 try/catch를 굳이 쓸 필요는 없으니 코드가 더 간단해질 수도 있습니다. 

 

 

 

 

 

예제 : <button>을 누르면 성공하는 Promise 만들기

Q. HTML 페이지 내에 버튼 아무거나 하나 만들고

그걸 클릭하면 성공하는 Promise를 만들고 싶습니다. 

성공하면 콘솔창에 '성공했어요'를 출력하고요.

어떻게 코드를 짜면 될까요? 

(async, await이 필요하면 써봅시다)

 

 

전 이렇게 짰습니다.

1. 일단 위의 버튼을 누르면 성공판정을 내리는 Promise를 만들었습니다.

그건 별거 아닙니다. 

 

2. 근데 이제 그게 성공하면 console.log()를 해주는 코드를 짜려고 봤더니 then을 쓰기 싫어서

await 프로미스;  이렇게 작성했습니다. 

 

3. 근데 await 을 쓰려면 async functinon 안에서만 쓸 수 있댔죠?

그래서 await 프로미스; 코드를 async function을 하나 만들어서 감쌌을 뿐입니다. 

 

 

 

 

혹은 이렇게 짜셨을 수도 있겠군요.

▲근데 위의 코드는 잘 동작하지 않습니다.

async가 Promise를 퉤 뱉는다고해서 async function 프로미스() 를 쓰고 이벤트리스너를 안에 담긴 했는데

버튼 누르면 return 어쩌구에 의해서 성공판정이 될거라고 기대했지만 안됩니다.

실은 return '성공했어요' 이게 async function의 return이 아니고 이벤트리스너안의 함수의 return문이라 문제되는 것도 있지만 

그것보다 더 중요한 문제는 이겁니다.

 

1. 이벤트 리스너안의 코드는 바로 실행되지 않습니다. 버튼 누를 때 실행됩니다.

2. 그래서 컴퓨터가 코드를 쭉 읽을 때 async function 프로미스() 함수 내부는 빈칸과 동일합니다.

3. 자바스크립트는 function 안이 빈칸이면 그냥 자동으로 return undefined 를 채워 실행합니다.  

(그럼 3번에 의해서 async function 프로미스()는 0초만에 자동으로 성공()판정이 됩니다)

 

 

그래서 하단의

var 결과 = await 프로미스();

이 코드는 프로미스()가 0초만에 성공판정이 내려진 상태로 실행되며 (그 함수에 return undefined가 자동으로 채워지니까요)

var 결과 = undefined 와 동일한 뜻입니다.

그래서 코드가 이상해진 것입니다. 

 

 

하지만 Promise로 만들어서 직접 성공(), 실패() 경우를 지정해준다면

await이 잘 기다려줍니다. 

 

 

 

 

 

출처 : 코딩애플의 매우쉽게 이해하는 JavaScript 객체지향 & ES6 신문법