實務上有些邏輯在 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 finally
block,繼續使用 imperative 思維
Reference
Marius Schulz, Execute Cleanup Logic in a JavaScript Promise Chain with Promise.prototype.finally()
MDN, Promise.prototype.finally()