Promise.prototype.finally()

finally() メソッドは Promise を返します。プロミスが確立したら、満足か拒否かにかかわらず、指定されたコールバック関数が実行されます。これにより、プロミスが成功裏に実行されたか否かに関わりなく、 Promise が処理された後に実行されなければならないコードを提供できます。

これによって、プロミスの then() ハンドラーと catch() ハンドラーでコードが重複することを避けることができます。

構文

p.finally(onFinally);

p.finally(function() {
   // 確立 (満足または拒否)
});

引数

onFinally
Promise が確立したら呼び出される Function

返値

finally ハンドラーに指定した onFinally が設定した Promise を返します。

解説

プロミスが確立した後、結果に関わらず何らかの処理や後始末を行いたいなら、finally() メソッドは役立ちます。

finally() メソッドは .then(onFinally, onFinally) の呼び出しとよく似ていますが、いくつかの点が異なります。

  • 関数をインラインで作成する場合、関数を 2 度宣言するか、変数を作成するかのどちらかで、一度に渡すことができます。
  • プロミスが満足したか拒否されたかを知る術がないため、finally コールバックは一切引数を受け取りません。このユースケースは、拒否された理由や履行された値などを提供する必要がなく、それらを気にしないときに適しています。
    • Promise.resolve(2).then(() => {}, () => {}) (undefined で解決される) と異なり、Promise.resolve(2).finally(() => {})2 で解決される。
    • 同様に、Promise.reject(3).then(() => {}, () => {}) (undefined で解決される) と異なり、Promise.reject(3).finally(() => {})3 で拒否される。

補足: finally コールバック内で throw が行われた場合 (または、拒否されたプロミスを返した場合)、 throw を呼び出すときに指定された拒否理由と共に新しいプロミスが拒否されます。

finally の使用

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.error(error); /* this line can also throw, e.g. when console = {} */ })
  .finally(function() { isLoading = false; });

仕様書

仕様書
ECMAScript (ECMA-262)
Promise.prototype.finally の定義

ブラウザーの互換性

BCD tables only load in the browser

関連情報