JavaScript의 Promise.finally() 메서드는 프로미스가 이행(fulfilled)되었든 거부(rejected)되었든 상관없이 항상 콜백 함수를 호출합니다. 즉, 프로미스가 성공했는지 실패했는지와 무관하게 마지막에 반드시 실행해야 하는 작업을 처리할 때 매우 유용합니다.
예를 들어 로딩 스피너 숨기기, 서버 연결 종료, 임시 리소스 정리처럼 성공·실패 여부와 관계없이 공통으로 수행해야 하는 후처리 작업을 finally() 블록에 작성하면 then()과 catch()에 동일한 코드를 중복해서 넣을 필요가 없어 코드가 훨씬 깔끔해집니다.
Promise.finally()의 주요 특징
- 콜백 함수가 어떠한 인수도 받지 않기 때문에 프로미스의 결과값이나 에러 객체에는 직접 접근할 수 없습니다.
- finally()는 새로운 프로미스를 반환하며, 원래 프로미스의 결과(값 또는 에러)를 그대로 다음 체인으로 전달합니다.
- ES2018부터 표준에 포함되어 모든 최신 브라우저에서 사용할 수 있습니다.
예제 코드
다음은 fetch API와 함께 Promise.finally()를 사용하는 전체 예제입니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.result {
font-size: 20px;
font-weight: 500;
}
</style>
</head>
<body>
<h1>Promise.finally in JavaScript</h1>
<div style="color: green;" class="result"></div>
<button class="btn">CLICK HERE</button>
<h3>
Click on the above button to know when the promise finishes
</h3>
<script>
let btnEle = document.querySelector(".btn");
let resEle = document.querySelector(".result");
btnEle.addEventListener("click", () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((Response) => Response.json())
.then((res) => res)
.catch((err) => alert("error occured"))
.finally(() => (resEle.innerHTML = "Promise is finished"));
});
</script>
</body>
</html>코드 설명
버튼을 클릭하면 fetch()로 사용자 데이터를 요청하고, 응답을 JSON으로 변환한 뒤 결과를 반환합니다. 요청 과정에서 에러가 발생하면 catch()가 경고창을 띄우고, 마지막에 finally()가 성공·실패 여부와 관계없이 화면에 'Promise is finished'라는 문구를 출력합니다.
실행 결과
위 코드를 실행하면 다음과 같은 초기 화면이 나타납니다.

'CLICK HERE' 버튼을 클릭하고 몇 초간 기다리면 프로미스가 완료되면서 아래와 같이 완료 메시지가 표시됩니다.