티스토리 뷰
비동기 처리는 함수를 호출하고 실행결과가 반환이 될 때까지 다른 작업을 진행하다가, 처리가 완료되었다는 이벤트를 수신하였을 때 작업을 마저 처리하는 방식입니다. Promise, Async를 이용하면 비동기 처리 로직을 쉽게 작성할 수 있습니다. Await를 사용하면 비동기 처리 API를 동기식 처리로 전환 가능하여, 로직의 실행 순서를 제어할 수 있습니다. 이번 포스팅에서는 Node.js에서 Promise, Await, Async를 이용하여 비동기식, 동기식 코드를 작성하는 방법에 대해 알아보겠습니다. Node.js에서 동기, 비동기 처리 원리에 대해 궁금하신분은 아래 포스팅 참고바랍니다.
Promise로 비동기 처리 로직 작성하기
Promise는 자바 스크립트에서 비동기 처리 로직을 다루기 위한 객체입니다. Promise 객체를 생성할 때, Callback함수를 인자로 작성합니다. 일반적으로, callback 함수에 비동기 처리 API를 호출하는 코드를 작성합니다. 콜백 함수의 파라미터로 resolve와 reject가 주어집니다. callback 함수가 성공적으로 수행되면 resolve()를 호출하고, callback 함수의 실행이 실패되었다면 reject()를 호출합니다. Promise함수 작성 및 호출하는 코드는 아래와 같이 작성합니다.
function promiseTest() {
return new Promise((resolve, reject) => {
try{
// 함수 작성
setTimeout(() => { resolve('Success') },1000)
} catch (err) {
reject('Fail') // 또는 throw new Error('error')
}
})
}
function main() {
promiseTest().then(data => {
console.log(data)
}).catch(err => {
console.log('ERROR : ' + err)
})
console.log('End')
}
main()
소스코드를 실행한 결과, 프로미스에서 resolve를 호출하면, then()이 실행됩니다. 만약, 프로미스에서 reject가 호출되면, catch가 실행됩니다. 프로미스 함수 내부에서 Exception이 발생해도 catch 블록이 실행됩니다. promiseTest 함수가 호출되면, 프로미스 내부에 비동기 처리 API인 setTimeout를 실행합니다. setTimeout는 실행만 하고 promiseTest함수를 빠져나와, 계속 스크립트 실행을 이어나갑니다. 'End'가 출력된 후, 1초 뒤 timeout에 정의한 콜백 함수에서 resolve가 호출되어 then함수 내부의 console.log함수가 실행되어 'Success'를 출력되고, 프로그램은 종료됩니다.
비동기 처리는 성능 관점에서는 효율이 좋지만, 소스코드를 이해하고 유지 보수하는 개발자 입장에서는 가독성이 좋지 않습니다. async, await는 비동기 처리 로직을 쉽게 작성할 수 있을 뿐만 아니라, 비동기 처리를 동기식 처리 로직으로 변환할 수 있습니다. 다음으로, async와 await에 대해 알아보겠습니다.
async, await으로 Promise를 동기식 처리로 작성하기
앞에서 구현한 비동기 처리 로직을 동기식으로 변경하는 방법이 있습니다. 예전에는 콜백 함수 안에 콜백 함수를 계속 구현하여, 비동기 처리 로직을 동기식으로 변환하였는데, 이러한 코드 작성 패턴으로 인해 콜백 지옥을 경험하는 경우가 많았습니다. 하지만, await과 async를 사용하면, 비동기 처리 로직을 동기식 처리로 변경 가능합니다.
await은 Promise가 종료될 때까지 대기하도록 지시하는 키워드입니다. async는 함수가 항상 프로미스로 반환되도록 지시하는 키워드입니다. async function의 반환 값은 명시하지 않아도 항상 Promise.resolve()로 치환되어 값이 반환됩니다. 궁금하시다면, async function의 반환 값을 출력해보면 Promise 객체가 출력되는 것을 확인할 수 있습니다. 다시 돌아와서, 앞에서 구현한 promiseTest함수를 await과 async 키워드를 이용하여, 동기식 처리로 변경해보겠습니다.
function promiseTest() {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log('Success')
resolve()
},1000)
})
}
async function main() {
try {
await promiseTest()
console.log('End')
} catch(err) {
console.log('ERROR : ' + err.message)
}
}
main()
기존에 작성한 코드와 다른 점은 promiseTest함수를 호출할 때 await가 추가되었고, main함수 정의에 async가 추가된 것입니다. await은 async function 내에서만 사용할 수 있는 키워드입니다. 만약, 일반 함수에서 await를 사용하면 아래와 같은 오류가 출력됩니다.
SyntaxError: await is only valid in async functions and the top level bodies of modules
main함수를 실행하면, promiseTest 함수에서 호출된 setTimeout이 종료될 때까지 기다린 후 프로미스가 종료되면 'End'가 출력됩니다.
async function내부에 try-catch 구문을 사용하였는데, 이는 promise의 then, catch를 사용한 것과 동일한 코드 작성 패턴입니다. await을 사용하여 then의 동작을 구현하고, catch는 동일하게 Exception을 잡는 역할을 합니다. 프로미스를 활용하여 비동기 처리를 개선하고자 하시는 분은 아래 포스팅도 함께 참고부탁드립니다.
지금까지 Promise, Async, Await을 이용하여 비동기, 동기 처리 로직을 작성하는 방법에 대해 알아보았습니다.
'IT 기술' 카테고리의 다른 글
Python, Selenium 기반 웹 자동화 테스트 구현하기 (0) | 2023.02.20 |
---|---|
[Node.js] Promise.all을 활용한 비동기 코드 작성법 (0) | 2022.09.16 |
디자인 패턴 - 책임 연쇄(Chain of Responsibility) (0) | 2022.09.16 |
구글 애드센스 승인 후기 (22년 6월 기준) (0) | 2022.09.13 |
[Node.js] 비동기 처리 로직의 실행 원리 분석 (0) | 2022.09.13 |
- Total
- Today
- Yesterday
- springboot rest api 서버
- python
- notion
- 스프링부트빌드
- AWS
- springboot build
- codesmell 유형
- TCP/UDP
- MPA
- SPA
- token
- springboot 실행
- 코드스멜 유형
- 스프링부트 restapi
- 클린코드작성원칙
- springboot restapi
- API Gateway 캐싱
- C++
- notion 업무일정관리
- oracle 메모리
- selenium
- 멀티코어 멀티프로세서
- 클린코드작성법
- 디자인패턴 구조패턴
- 테스팅 자동화
- iframe 태그 찾기
- 디자인패턴
- OSI 7계층
- 스프링부트실행
- oracle pga sga
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |