Promise.prototype.finally
可註冊一個回呼函式,在 promise 已解決(例如已完成或已拒絕)時呼叫。
想像一下,你想要擷取一些資料並顯示在頁面上。喔,而且你想要在要求開始時顯示一個載入指示器,並在要求完成時隱藏它。當出現問題時,你會顯示錯誤訊息。
const fetchAndDisplay = ({ url, element }) => {
showLoadingSpinner();
fetch(url)
.then((response) => response.text())
.then((text) => {
element.textContent = text;
hideLoadingSpinner();
})
.catch((error) => {
element.textContent = error.message;
hideLoadingSpinner();
});
};
fetchAndDisplay({
url: someUrl,
element: document.querySelector('#output')
});
如果要求成功,我們會顯示資料。如果出現問題,我們會顯示錯誤訊息。
在任一種情況下,我們都需要呼叫 hideLoadingSpinner()
。到目前為止,我們別無選擇,只能在 then()
和 catch()
區塊中重複這個呼叫。有了 Promise.prototype.finally
,我們可以做得更好
const fetchAndDisplay = ({ url, element }) => {
showLoadingSpinner();
fetch(url)
.then((response) => response.text())
.then((text) => {
element.textContent = text;
})
.catch((error) => {
element.textContent = error.message;
})
.finally(() => {
hideLoadingSpinner();
});
};
這不僅減少了重複的程式碼,也更清楚地將成功/錯誤處理階段和清除階段分開。太棒了!
目前,使用 async
/await
也可以做到相同的事情,而且不需要 Promise.prototype.finally
const fetchAndDisplay = async ({ url, element }) => {
showLoadingSpinner();
try {
const response = await fetch(url);
const text = await response.text();
element.textContent = text;
} catch (error) {
element.textContent = error.message;
} finally {
hideLoadingSpinner();
}
};
由於 async
和 await
絕對更好,因此我們建議使用它們,而不是純粹的 promises。話雖如此,如果你因為某些原因而偏好純粹的 promises,Promise.prototype.finally
可以幫助讓你的程式碼更簡單、更乾淨。
Promise.prototype.finally
支援 #
- Chrome: 自版本 63 起支援
- Firefox: 自版本 58 起支援
- Safari: 自版本 11.1 起支援
- Node.js: 自版本 10 起支援
- Babel: 支援