Promise.prototype.finally は、プロミスが解決している(つまり、完了しているか拒否されている)ときに呼び出されるコールバックを登録できます。
ページに表示するいくつかのデータを取得したいと考えてみましょう。ああ、リクエストが開始したらローディングスピナーを表示し、リクエストが完了したら非表示にしたいのです。何か問題が発生した場合は、代わりにエラーメッセージを表示します。
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 は、明確に優れていますので、バニラプロミスではなくそれらを使用することをお勧めします。とはいえ、何らかの理由でバニラプロミスを好む場合は、 Promise.prototype.finally はコードをよりシンプルでクリーンにするのに役立ちます。
Promise.prototype.finally サポート #
- Chrome: バージョン 63 以降でサポート
- Firefox: バージョン 58 以降でサポート
- Safari: バージョン 11.1 以降でサポート
- Node.js: バージョン 10 以降でサポート
- Babel: サポートされています