
지난 글에서는 비동기 처리와 콜백 함수에 이어 Promise에 대해 살펴봤습니다. 해당 개념들이 익숙하지 않고 이번 글로 처음 들어오신 분들은 '비동기 처리와 콜백 함수' 및 'Promise' 글을 참고하는 것을 추천드립니다. 이번 글에서는 Javascript의 비동기 처리 문법 중 가장 최근에 나온 async & await에 대해 작성하고자 합니다. 제가 caver-js를 공부하다가 Promise pending 문제를 직면하였고, 해당 문제를 해결하기 위한 핵심이 async & await이므로, 이번 글에서는 caver-js를 바탕으로 설명드릴 것입니다. caver-js에 대해서도 알고 싶으신 분은 해당 글을 참고해 주시길 바랍니다.
다음 코드는 제가 비동기 처리, Promise, async & await에 대해 제대로 공부하지 않고, caver-js만을 공부하여 작성한 코드입니다. 각 함수들이 의미하는 바를 알기보다는 코드의 구조를 봐주시면 됩니다. 앞선 글에서 Promise의 결과를 받기 위해서는 then을 사용하고, Promise Chaining을 통해 콜백 지옥 문제도 해결할 수 있다고 하였습니다. 하지만 caver-js 라이브러리에 있는 상당 수의 함수들이 Promise를 반환합니다. then을 위주로 사용해서 코드를 작성하는 경우 아래의 코드처럼 들여 쓰기가 많이 되고 코드가 계속 이어지게 되어, 콜백 지옥처럼 코드 가독성이 떨어질 수 있습니다.
function testFunction() {
caver.rpc.klay.getLogs({
...
}).then((response) => {
...
caver.rpc.klay.getTransactionByHash().then((respons) => {
...
const date = caver.klay.getBlock(blockNb).then((response) => {
...
})
}
})
}
다른 글에서는 Promise만으로 비동기 처리를 하는 경우, then을 연쇄적으로 호출하여 몇 번째 then에서 오류가 발생한 지 파악하기 어렵고, 디버깅 및 예외 처리 과정에서도 불편한 점이 발생할 수 있다고 합니다.
이러한 Promise의 문제점을 해결하기 위해 등장한 것이 async & await입니다. async는 함수 앞에 사용하며, await는 비동기 함수 앞에 사용합니다. await를 사용하면, 비동기 처리로 인해 다음 코드로 넘어가는 것이 아니라 결과를 얻을 때까지 기다리며, 비동기 함수가 반환하는 Promise로부터 결과값을 바로 추출할 수 있게 됩니다. 따라서 async & await는 비동기 코드를 동기 코드와 같이 작성하여 코드의 가독성을 높인다는 장점이 있습니다.
위의 코드도 단순히 then으로 잇는 것이 아니라, 다음의 코드와 같이 async & await를 적용하면 더 깔끔하게 정리할 수 있습니다. 위의 코드에서는 함수의 결과를 계속해서 then으로 이었지만, 아래의 코드에서는 변수로 할당하여 추후에 결과를 활용하기도 수월해졌습니다.
async function testFunction() {
const log = await caver.rpc.klay.getLogs({
...
});
...
const tx = await caver.rpc.klay.getTransactionByHash();
...
const date = await caver.klay.getBlock(blockNb);
...
}
다만 async를 사용할 경우, Promise 객체를 생성하지 않아도 해당 함수의 결과가 Promise로 반환되게 됩니다. 따라서 함수 내에 await를 사용하던지, 혹은 함수 뒤에 then을 사용하여 결과를 받아야 합니다.
그럼 다시 처음 글의 문제로 돌아가겠습니다. Promise를 반환하는 getBlockNumber() 함수의 결과를 변수에 할당하고 싶었지만, test라는 변수에 할당한 이후 결과를 출력하면 'Promise { <pending> }'이 나오게 됩니다.
function testFunction() {
// Get Recent Block Number
const test = caver.klay.getBlockNumber();
console.log(test);
}
testFunction()
PS C:\...\project> node test.js
Promise { <pending> }
이번 글에서 학습한대로 함수 앞에 async를 추가하고 비동기 함수 앞에 await를 추가하면, 생각보다 간단하게 원하는 결과인 블록 넘버를 얻을 수 있게 됩니다.
async function testFunction() {
// Get Recent Block Number
const test = await caver.klay.getBlockNumber();
console.log(test);
}
testFunction()
PS C:\...\project> node test.js
109678454
단순히 Promise Pending 문제를 해결하고 싶었는데, 오류를 파헤치면서 비동기 처리부터 콜백 함수, Promise, async & await까지 공부하게 되었습니다. 처음 오류를 직면하였을 때, 해결하는 방법만 찾다 보니 뒤에 then을 붙이고 resolve를 사용하는 등 며칠 동안 오류를 해결하지 못하였습니다. 결국 근본적인 개념에 접근하게 되었고, 생각보다 손쉽게 오류를 해결할 수 있었습니다. 다른 분들도 저 같은 문제에 직면하게 되면, 근본적인 개념을 한 번 공부하는 것을 추천드립니다.
앞서 작성한 글을 비롯하여 이번 글까지 혼자 공부하여 작성한 것이므로 틀린 부분이 있을 수 있습니다. 틀린 부분이 있으면 댓글로 알려주시길 바랍니다. 다음 글부터는 다시 caver-js로 돌아가 블록체인 데이터 수집에 대해 살펴보겠습니다.
[이전 글]
1) [JavaScript] Promise { <pending> } 문제 해결 (1) - 비동기 처리 및 콜백 함수
2) [JavaScript] Promise { <pending> } 문제 해결 (2) - Promise
<참고>
https://joshua1988.github.io/web-development/javascript/js-async-await/
자바스크립트 async와 await
(중급) 자바스크립트 개발자를 위한 async, await 사용법 설명. 쉽게 알아보는 자바스크립트 async await 개념, 사용법, 예제 코드, 예외 처리 방법
joshua1988.github.io
https://www.daleseo.com/js-async-async-await/
[자바스크립트] 비동기 처리 3부 - async/await
Engineering Blog by Dale Seo
www.daleseo.com
'Front-end > JavaScript' 카테고리의 다른 글
| [JavaScript] Promise { <pending> } 문제 해결 (2) - Promise (2) | 2022.12.19 |
|---|---|
| [JavaScript] Promise { <pending> } 문제 해결 (1) - 비동기 처리 및 콜백 함수 (4) | 2022.12.19 |
댓글