Promise.prototype.finally

公開 · ECMAScript ES2018 でタグ付け

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/awaitPromise.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();
}
};

asyncawait は、明確に優れていますので、バニラプロミスではなくそれらを使用することをお勧めします。とはいえ、何らかの理由でバニラプロミスを好む場合は、 Promise.prototype.finally はコードをよりシンプルでクリーンにするのに役立ちます。

Promise.prototype.finally サポート #