Promise.prototype.finally()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itโs been available across browsers since โจ2018๋ 10์โฉ.
Promise
์ธ์คํด์ค์ finally()
๋ฉ์๋๋ ํ๋ก๋ฏธ์ค๋ฅผ ์ฒ๋ฆฌํ ํ(์ดํ๋๊ฑฐ๋ ๊ฑฐ๋ถ๋ ํ) ํธ์ถํ ํจ์๋ฅผ ์์ฝํฉ๋๋ค.
์ด ๋ฉ์๋๋ ์ฆ์ ๋๋ฑํ Promise
๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฏ๋ก ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด ๊ฐ๋ฅํฉ๋๋ค.
finally()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด then()
์ catch()
์ฒ๋ฆฌ๊ธฐ ์ ์ฝ๋ ์ค๋ณต์ ํผํ ์ ์์ต๋๋ค.
์๋ํด ๋ณด๊ธฐ
function checkMail() {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve("Mail has arrived");
} else {
reject(new Error("Failed to arrive"));
}
});
}
checkMail()
.then((mail) => {
console.log(mail);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log("Experiment completed");
});
๋ฌธ๋ฒ
promiseInstance.finally(onFinally)
๋งค๊ฐ๋ณ์
onFinally
-
ํ๋ก๋ฏธ์ค๊ฐ ์ฒ๋ฆฌ๋ ํ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋ ํจ์์ ๋๋ค. ๊ฑฐ๋ถ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ์ง ์๋ ์ด์ ๋ฐํ ๊ฐ์ ๋ฌด์๋ฉ๋๋ค. ํจ์๋ ์ธ์ ์์ด ํธ์ถ๋ฉ๋๋ค.
๋ฐํ ๊ฐ
๋ฐํ ๊ฐ์ ์ธ์คํด์ค์ ๋์ผํ Promise
์
๋๋ค. ๋ง์ฝ ์ฒ๋ฆฌ๊ธฐ์์ ์์ธ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๊ฑฐ๋ถ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ฉด, finally()
๊ฐ ๋ฐํํ ํ๋ก๋ฏธ์ค๋ ๋์ ๊ทธ ๊ฐ์ผ๋ก ๊ฑฐ๋ถ๋ฉ๋๋ค. ์ด์ธ์๋ ์ฒ๋ฆฌ๊ธฐ์ ๋ฐํ ๊ฐ์ ์๋ ํ๋ก๋ฏธ์ค์ ์ํ์ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค.
์ค๋ช
finally()
๋ฉ์๋๋ ๊ฒฐ๊ณผ์ ๊ด๊ณ์์ด ํ๋ก๋ฏธ์ค๊ฐ ์ฒ๋ฆฌ๋๊ณ ๋์ ๋ฌด์ธ๊ฐ๋ฅผ ์ฒ๋ฆฌํ๊ฑฐ๋ ์ ๋ฆฌํ ๋ ์ ์ฉํฉ๋๋ค.
finally()
๋ฉ์๋๋ then(onFinally, onFinally)
๋ฅผ ํธ์ถํ๋ ๊ฒ๊ณผ ๋งค์ฐ ๋น์ทํ์ง๋ง ๋ช ๊ฐ์ง ์ฐจ์ด์ ์ด ์์ต๋๋ค.
- ํจ์๋ฅผ ์ธ๋ผ์ธ์ผ๋ก ๋ง๋ค ๋, ๋ ๋ฒ ์ ์ธํ๊ฑฐ๋ ๋ณ์์ ํ ๋นํ ํ์ ์์ด ํ ๋ฒ๋ง ์ฌ์ฉํด์ ์ ๋ฌํ ์ ์์ต๋๋ค.
onFinally
์ฝ๋ฐฑ์ ์ธ์๋ฅผ ๋ฐ์ง ์์ต๋๋ค. ์ดํ๋ ๊ฐ ํน์ ๊ฑฐ๋ถ๋ ์ด์ ์ ๋ฌด๊ดํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ์๋ง ์คํ๋๋ฏ๋ก ์ธ์๊ฐ ํ์ํ์ง ์์ต๋๋ค.finally()
ํธ์ถ์ ๋ณดํต ์ธ๋ถ์ ์ํฅ์ ๋ฐ์ง ์์ผ๋ฉฐ ์๋ ํ๋ก๋ฏธ์ค์ ์ต์ข ์ํ๋ฅผ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค. ๋ค์ ์์๋ฅผ ์ฐธ๊ณ ํ์ธ์.Promise.resolve(2).then(() => 77, () => {})
๋77
๋ก ์ดํ๋ฉ๋๋ค. ์ด์๋ ๋ค๋ฅด๊ฒ,Promise.resolve(2).finally(() => 77)
๋2
๋ก ์ดํ๋ฉ๋๋ค.- ์ ์ฌํ๊ฒ
Promise.reject(3).then(() => {}, () => 88)
๋88
๋ก ๊ฑฐ๋ถ๋ฉ๋๋ค. ์ด์๋ ๋ฌ๋ฆฌPromise.reject(3).finally(() => {})
๋3
๋ก ๊ฑฐ๋ถ๋ฉ๋๋ค.
์ฐธ๊ณ :
finally
์ฝ๋ฐฑ ๋ด ์์ธ ๋ฐ์ ๋๋ ๊ฑฐ๋ถ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ ๊ฒฝ์ฐ์๋ ๊ฑฐ๋ถ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ดPromise.reject(3).finally(() => { throw 99; })
์Promise.reject(3).finally(() => Promise.reject(99))
๋ ๋ชจ๋99
๋ก ๊ฑฐ๋ถ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค.
catch()
์ฒ๋ผ , finally()
๋ ๋ด๋ถ์ ์ผ๋ก ์์ ์ ํธ์ถํ ๊ฐ์ฒด์ then
๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. onFinally
๊ฐ ํจ์๊ฐ ์๋ ๊ฒฝ์ฐ, then()
์ ๋ ์ธ์ ๋ชจ๋ onFinally
๋ก ๋์ด๊ฐ ํธ์ถ๋๋ฉฐ, ์ฆ Promise.prototype.then()
์๊ฒ ์ ์ฉํ ์ฒ๋ฆฌ๊ธฐ๊ฐ ํฌํจ๋์ง ์๋๋ค๋ ์๋ฏธ์
๋๋ค. ๊ทธ ์ธ์ ๊ฒฝ์ฐ then()์ ๋ด๋ถ์ ์ผ๋ก ์์ฑ๋ ๋ ๊ฐ์ ํจ์์ ํจ๊ป ํธ์ถ๋๋ฉฐ, ๋ค์๊ณผ ๋น์ทํ๊ฒ ๋์ํฉ๋๋ค.
๊ฒฝ๊ณ : ๋ค์์ ์ค๋ช ์ ์ํ ์์์ด๋ฉฐ ์ค์ ํด๋ฆฌํ์ด ์๋๋๋ค.
promise.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) =>
Promise.resolve(onFinally()).then(() => {
throw reason;
}),
);
finally()
๋ฉ์๋๊ฐ then()
์ ํธ์ถํ๊ธฐ ๋๋ฌธ์ ์๋ธํด๋์ฑ์ ์ง์ํฉ๋๋ค. ์ ์์์ Promise.resolve()
ํธ์ถ์ ์ฃผ๋ชฉํ์ธ์. ์ค์ ๋ก onFinally()
์ ๋ฐํ ๊ฐ์ Promise.resolve()
์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ดํ๋ฉ๋๋ค. ํ์ง๋ง ์ดํ๋ ํ๋ก๋ฏธ์ค์ ์ง์ง ์์ฑ์๋ ์๋ธํด๋์ค๊ฐ ๋ฉ๋๋ค. finally()
๋ ์ด ์์ฑ์๋ฅผ promise.constructor[@@species]
์์ ์ป์ต๋๋ค.
์์
finally()
์ฌ์ฉํ๊ธฐ
let isLoading = true;
fetch(myRequest)
.then((response) => {
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then((json) => {
/* JSON ์ฒ๋ฆฌ */
})
.catch((error) => {
console.error(error); // ์ด ์ค๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. (์: console = {})
})
.finally(() => {
isLoading = false;
});
๋ช ์ธ์
Specification |
---|
ECMAScriptยฎ 2026 Language Specification # sec-promise.prototype.finally |
๋ธ๋ผ์ฐ์ ํธํ์ฑ
Loadingโฆ