코드 스터디
for루프 비동기 구문을 프로미스로 해결하기
Recstasy
2022. 6. 1. 08:47
웹 프로그래밍에서 '비동기 구문'은 스파게티 코드의 주범이다.
그 중에서도 for루프 구문과 비동기 방식은 더욱 주의가 필요하다. 특히, 함수 내부에 있는 for루프 구문에서 외부 함수를 끌어들이는 상황이 대표적이다. 가령, 아래 코드에서 waitCode함수 내부의 for루프는 outerCode함수를 참조한다.
waitCode();
function waitCode() {
let testNum = 0;
for(let i = 0; i < 10; i++ ) {
testNum += outerCode( i, 100 );
}
console.log( 'testNum: ' + testNum );
}
function outerCode( val, milisec ) {
setTimeout( () => {
console.log('setTimeout 실행')
return val;
}, milisec )
}
|
「코드 1」
위의 코드를 실행해보면, outerCode함수가 실행되기도 전에 'console.log('testNum: ' + testNum)'구문이 실행된다. 이른바 비동기 방식의 딜레마다. 만일, outerCode함수가 고객 정보와 같은 핵심적인 데이터를 갖고 있다면, 위의 코드는 치명적인 에러를 발생시킨다.
그렇다면, 위의 코드에서 waitCode함수에 있는 for루프구문이 끝난 뒤, testNum값을 console로 찍어내려면 어떻게 해야 할까? 답은 Promise다. 우선, 위의 코드에서 async-await구문을 waitCode함수 내에 적용해준다. 그리고 outerCode함수의 반환값에 Promise를 씌운다.
waitCode(); async function waitCode() {
let testNum = 0;
for(let i = 0; i < 10; i++ ) {
testNum += await outerCode( i, 1000 );
}
console.log( 'testNum: ' + testNum );
}
function outerCode( val, milisec ) {
return new Promise( resolve => {
setTimeout( () => {
console.log('setTimeout 실행');
resolve( val )
}, milisec )
})
}
|
「코드 2」
'코드2' 실행 결과, waitCode함수 내의 for루프가 끝나기 전까지 'console.log('testNum:' + testNum)'구문이 실행되지 않는 것을 확인할 수 있다.
위의 예제는 비교적 간단하지만, 비동기 구현이 난잡한 실제 개발에서 상당히 유용하게 사용할 수 있다.