JavaScript에서 forEach, map 함수 내에서 throw Error가 되지 않을 때 해결 방법
많은 JavaScript 개발자들이 배열을 처리할 때 map
함수를 즐겨 사용합니다. 그러나 때때로 예상치 못한 문제에 부딪힐 수 있습니다. 이 글에서는 map 함수 내에서 throw Error
가 작동하지 않는 상황을 해결하는 방법에 대해 알아보겠습니다.
1. 문제 상황 파악
자바스크립트의 map/forEach
함수는 배열의 각 요소에 대해 주어진 함수를 호출하고, 그 결과를 모아 새로운 배열을 반환합니다. 때로는 배열 내의 특정 요소에 대한 조건을 검사하고 해당 조건이 충족되지 않을 경우 에러를 발생시키고 싶을 때가 있습니다.
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => {
if (num > 3) {
throw new Error('Number is too big');
}
return num * 2;
});
이 코드에서 숫자 4와 5는 3보다 크기 때문에 오류를 발생시키려고 했지만, 실제로는 그렇게 동작하지 않습니다. 이러한 상황이 발생하는 주된 원인은 map/forEach
함수가 동기적으로 동작하기 때문입니다.
2. Promise와 함께 사용하는 경우
비동기 작업을 수행할 때 Promise
와 함께 map/forEach
함수를 사용하면 예외 처리가 더 복잡해질 수 있습니다. Promise
에서 발생한 오류는 .catch
메소드를 통해 캐치할 수 있습니다.
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(async num => {
if (num > 3) {
throw new Error('Number is too big');
}
return num * 2;
});
Promise.all(doubled).catch(error => console.error(error.message));
위 코드에서 Promise.all
은 모든 프로미스가 성공적으로 완료되거나 첫 번째 프로미스가 거부될 때까지 기다립니다. 이렇게 하면 map
내에서 발생하는 오류를 캐치할 수 있습니다.
3. 해결 방법
map 함수 내에서 명시적으로 예외처리
가장 간단한 해결책은 map/forEach
함수 내에서 발생하는 예외를 명시적으로 캐치하는 것입니다.
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => {
try {
if (num > 3) {
throw new Error('Number is too big');
}
return num * 2;
} catch (error) {
console.error(error.message);
return null;
}
});
위 코드에서는 각 숫자를 처리하는 동안 오류가 발생하면 콘솔에 오류 메시지가 출력되고 해당 숫자의 결과 값은 null이 됩니다.
for ... of 를 사용하는 방법
for...of
를 사용하면 반복문 내에서 개별 요소에 접근하면서 에러를 직접 처리할 수 있습니다. 이 방식은 코드의 명확성을 높여줍니다.
const numbers = [1, 2, 3, 4, 5];
const doubled = [];
for (const num of numbers) {
if (num > 3) {
console.error('Number is too big');
} else {
doubled.push(num * 2);
}
}
3.3 Promise.all을 사용하는 방법
비동기 작업을 수행할 때 Promise와 함께 map
함수를 사용하면, Promise에서 발생한 오류는 .catch
메소드를 통해 캐치할 수 있습니다.
const numbers = [1, 2, 3, 4, 5];
const doubledPromises = numbers.map(num => {
return new Promise((resolve, reject) => {
if (num > 3) {
reject(new Error('Number is too big'));
} else {
resolve(num * 2);
}
});
});
Promise.all(doubledPromises)
.then(results => console.log(results))
.catch(error => console.error(error.message));
이렇게 Promise.all
을 사용하면, 모든 프로미스가 성공적으로 완료되거나 첫 번째 프로미스가 거부될 때까지 기다리게 됩니다.
마치며
이 세 가지 방법을 적절하게 활용하면, map/forEach
함수 내에서의 오류 처리 문제를 효과적으로 해결할 수 있습니다. 필요에 따라 적합한 방법을 선택하면, 예상치 못한 문제를 효과적으로 대응하고 코드의 안정성을 높일 수 있습니다.