자바스크립트에서 try - catch - finally 구문은 예외 처리를 위한 강력한 도구입니다. 이 구문에서 finally 블록은 예외 발생 여부와 관계없이 항상 실행되는 코드 블록으로, 주로 리소스 정리나 마무리 작업에 사용됩니다.
finally?
finally는 일반적으로 try나 catch 뒤에 붙으면서, try나 catch 문의 동작이 모두 완료되었을 때 무조건 실행되는 코드를 작성하기 위해 사용합니다. finally 블록은 선택 사항이기 때문에 생략하는 경우가 많습니다.
finally가 어떻게 동작하는지 간단하게 짚고 넘어가겠습니다.
지금부터 주목해야할 점은 무조건 실행되는 코드입니다. 예시로 확인해보겠습니다.
예시 (1)
try {
console.log('Try');
} catch(error) {
console.log('Catch');
} finally {
console.log('Finally');
}
Try
Finally
try 블록에서 에러가 발생하지 않았기 때문에, catch 블럭은 실행하지 않고 finally 블럭을 바로 실행하는 모습을 보여줍니다.
예시 (2)
try {
console.log('Try');
throw new Error();
} catch(error) {
console.log('Catch');
} finally {
console.log('Finally');
}
Try
Catch
Finally
try 블록에서 에러가 발생했기 때문에, catch 블럭을 실행하고 finally 블럭을 실행하는 모습을 보여줍니다.
finally 구문이 무조건 실행되긴 하지만, 여기까지 봐서는 아직 무조건 실행되는 코드에 대한 의문이 풀리지 않았죠?
궁금증을 해결하기 위해 try-catch-finally 구문을 함수에 넣어 실행해 보겠습니다.
함수에 try - catch - finally 구문 넣기
function test() {
try {
console.log('try');
} catch(error) {
console.log('catch');
} finally {
console.log('finally');
}
}
test();
위 코드를 실행하면 어떤 결과가 나올까요❓
Try
Finally
위에서 봤던 예시 코드를 test라는 함수에 넣은 것이니 간단하죠😀
이제부터 finally의 무조건 실행되는 코드에 대한 내용을 직접 확인해 보겠습니다❗
확인에 앞서 함수의 return 명령문에 대해서 간략하게 설명하겠습니다.
return 명령문
함수 실행을 종료하고, 주어진 값을 함수 호출 지점으로 반환합니다.
(출처: MDN return)
함수 실행을 종료하는 return 명령문이 있어도 finally 구문이 실행되는지 확인해 보겠습니다.
function test() {
try {
return 'try';
} catch(error) {
return 'error';
} finally {
return 'finally';
}
}
console.log(test());
return 명령문이 함수 실행을 종료시킨다고 했으니 try가 반환될까요?
finally가 무조건 실행되는 코드라고 했으니 finally가 반환될까요?
어떤 결과가 출력될지 예상이 되시나요🤔
아래 결과를 확인해 보시죠.
finally
try 블록에서 return 명령문에 의해 함수 실행을 종료하고 try를 반환해야 하는데, finally가 반환되었습니다.
여기서 의문이 생기죠. 왜 return 명령문이 있는데 함수 실행이 종료되지 않고 finally 구문이 실행되었을까요🤔
아래 내용은 ECMAScript에 정의된 return 명령문 내용입니다.
A return statement causes a function to cease execution and, in most cases, returns a value to the caller. If
Expression is omitted, the return value is undefined. Otherwise, the return value is the value of Expression. A
return statement may not actually return a value to the caller depending on surrounding context. For example, in a try block, a return statement's Completion Record may be replaced with another Completion Record during evaluation of the finally block.
간단하게 요약하면 아래 내용과 같습니다.
return명령문은 주변 컨텍스트에 따라 호출자에게 실제로 값을 반환하지 않을 수 있습니다. 예를 들어, try 블록의 return 명령문의 Completion Record가 finally 블록의 return 명령문의 Completion Record으로 대체될 수 있습니다.
시작부터 강조했던 finally는 무조건 실행되는 코드가 검증되었네요❗
여기서 한 가지 궁금증이 더 생겼습니다. finally 구문이 throw 문을 만나도 실행될까요🤔
try - catch - finally 구문에 throw로 예외 발생시키기
확인에 앞서 throw에 대해서 간략하게 설명하겠습니다.
throw 문은 사용자 정의 예외를 발생(throw)할 수 있습니다. 예외가 발생하면 현재 함수의 실행이 중지되고 (throw 이후의 명령문은 실행되지 않습니다.), 제어 흐름은 콜스택의 첫 번째 catch 블록으로 전달됩니다. 호출자 함수 사이에 catch 블록이 없으면 프로그램이 종료됩니다.
(출처: MDN throw)
예외 처리 후 함수 실행을 종료하는 throw 명령문이 있어도 finally 구문이 실행되는지 확인해 보겠습니다.
function test() {
try {
throw new Error();
} catch (e) {
throw new Error();
} finally {
return 'finally';
}
}
console.log(test());
throw 문이 함수 실행을 종료시킨다고 했으니 에러를 발생시키고 종료될까요?
finally가 무조건 실행되는 코드라고 했으니 finally가 반환될까요?
finally
catch 블록에서 throw 문이 실행되었지만 다음 catch 블록이 없어 프로그램이 종료되어야 하지만, finally가 반환되었습니다.
이로써 finally는 무조건 실행되는 코드라는 사실이 확인되었습니다❗❗❗
그럼 finally를 어떻게 사용하면 좋을까요🤔🤔
finally 활용 예시
- 메모리 누수 방지 : 비동기 작업 후 생성된 임시 변수나 데이터 구조를 정리하거나, 동적으로 추가한 이벤트 리스너를 작업이 끝난 후 제거하여 메모리 누수를 방지할 수 있습니다.
- 네트워크 연결 종료 : 네트워크 요청을 수행한 후, 예외 발생 여부와 관계없이 연결을 종료하여 리소스를 정리하는 데 finally 블록을 활용할 수 있습니다.
- 외부 API 호출 후 상태 복원 : 외부 API를 호출하여 상태를 변경한 후, 예외 발생 여부와 관계없이 원래 상태로 복원해야 하는 경우에 finally 블록을 사용하여 상태 복원을 보장할 수 있습니다.
추천글
'개발 공부 일지 > JavaScript' 카테고리의 다른 글
[JS] Reflow와 Repaint (4) | 2024.12.21 |
---|---|
[JS] 이벤트 루프(Event Loop)란? (5) | 2024.12.20 |
[JS] for ...of와 for ...in (4) | 2024.12.11 |
[JS] 자바스크립트의 == 와 === 의 차이 (4) | 2024.12.11 |
[JS] Promise.all 과 Promise.allSettled 차이 (5) | 2024.12.09 |