實務上有些邏輯在 Fulfilled Promise 與 Rejected Promise 都需被執行,導致 Fulfilled Handler 與 Rejected Handler 都寫了一份,此時可使用 ECMAScript 2018 的 finally() 與 try catch finally,只需寫一份邏輯即可。
Version
macOS Mojave 10.14.6
VS Code 1.38.1
Quokka 1.0.248
ECMAScript 2018
finally()
let fetchData = () => Promise.resolve('Hello World');
fetchData().then(
x => {
console.log(x);
console.log('Fetch completed');
}
).catch(
e => {
console.log(e);
console.log('Fetched completed');
}
);
若無論是 fulfilled promise 或 rejected promise,最後我們都希望印出 Fetched completed。
若只有 then() 與 catch(),則 fulfilled handler 與 rejected handler 都必須包含 console.log('Fetched completed')。

let fetchData = () => Promise.resolve('Hello World');
fetchData()
.then(x => console.log(x))
.catch(e => console.log(e))
.finally(() => console.log('Fetched completed'));
ES2018 提供了 finally(),可將 fulfilled handler 與 rejected handler 重複部分重構到 finally() 的 callback 中。

Try Catch Finally
let fetchData = () => Promise.resolve('Hello World');
try {
let x = await fetchData();
console.log(x);
} catch(e) {
console.log(e);
} finally {
console.log('Fetched completed')
}
自從 ES2017 可將 await 用於 try catch block 中之後,自然也能將 finally() 寫在 finally block 內。
這種寫法個符合 imperative 與 synchronous 習慣。

Conclusion
finally()能避免then()與catch()中有重複邏輯- 也可使用
try catch finallyblock,繼續使用 imperative 思維
Reference
Marius Schulz, Execute Cleanup Logic in a JavaScript Promise Chain with Promise.prototype.finally()
MDN, Promise.prototype.finally()