[Salesforce]JavaScript Promise の使用

JavaScript Promise の使用

JavaScript Promise の使用

JavaScript コードで ES6 Promise を使用できます。Promise により、非同期コールの成否を処理するコードや、複数の非同期コールをまとめてチェーニングするコードを簡素化できます。

ブラウザでネイティブバージョンが提供されない場合は、フレームワークがポリフィルを使用するため、Promise は Lightning Experience でサポートされるすべてのブラウザで機能します。

ここでは、Promise の基本を十分に理解していることを前提としています。Promise のわかりやすい概要については、https://developers.google.com/web/fundamentals/getting-started/primers/promises を参照してください。

Promise は省略可能な機能です。Promise を愛用している人もいれば、そうでない人もいます。各自の使用事例にとって有用であれば利用します。

Promise の作成

次の firstPromise 関数は、Promise を返します。

firstPromise : function() {
    return new Promise($A.getCallback(function(resolve, reject) {
      // do something
    
      if (/* success */) {
        resolve("Resolved");
      }
      else {
        reject("Rejected");
      }
    }));
}

この Promise のコンストラクタが、Promise で resolve() または reject() をコールする条件を決定します。

Promise のチェーニング

複数のコールバックを連携させたり、まとめてチェーニングしたりする必要があるときは Promise が役立ちます。汎用的なパターンは次のとおりです。

firstPromise()
    .then(
        // resolve handler
        $A.getCallback(function(result) {
            return anotherPromise();
        }),

        // reject handler
        $A.getCallback(function(error) {
            console.log("Promise was rejected: ", error);
            return errorRecoveryPromise();
        })
    )
    .then(
        // resolve handler
        $A.getCallback(function() {
            return yetAnotherPromise();
        })
    );

then() メソッドは、複数の Promise をチェーニングします。この例では、各解決ハンドラが別の Promise を返します。

then() は Promise API の一部です。次の 2 つの引数を取ります。

  1. 達成された Promise のコールバック (解決ハンドラ)
  2. 却下された Promise のコールバック (却下ハンドラ)

1 つ目のコールバック function(result) は、Promise コンストラクタで resolve() がコールされたときにコールされます。コールバックの result オブジェクトは、resolve() への引数として渡されるオブジェクトです。

2 つ目のコールバック function(error) は、Promise コンストラクタで reject() がコールされたときにコールされます。コールバックの error オブジェクトは、reject() への引数として渡されるオブジェクトです。

この例では、2 つのコールバックが $A.getCallback() でラップされています。どういうことでしょうか? Promise はその resolve 関数と reject 関数を非同期に実行するため、コードは Lightning イベントループおよび通常の表示ライフサイクルの外側に存在します。resolve または reject のコードによって、コンポーネント属性の設定など、Lightning コンポーネントフレームワークに何らかのコールを実行する場合は、$A.getCallback() を使用してコードをラップします。詳細は、「フレームワークのライフサイクル外のコンポーネントの変更」を参照してください。

catch() または却下ハンドラを常に使用

1 つ目の then() メソッドの却下ハンドラは、errorRecoveryPromise() が設定された Promise を返します。却下ハンドラは多くの場合、Promise チェーンの「中流」で使用され、エラー回復メカニズムをトリガします。

Promise API には、必要に応じて未処理のエラーを検出する catch() メソッドが含まれます。Promise チェーンには常に拒否ハンドラまたは catch() メソッドを含めます。

Promise でエラーが発生しても、フレームワークがグローバルエラーハンドラを設定する window.onerror はトリガされません。catch() メソッドがない場合は、開発時に、ブラウザのコンソールに Promise の未検出エラーに関するレポートがないか注意します。catch() メソッドにエラーメッセージを表示するには、$A.reportError() を使用します。catch() の構文は次のとおりです。

promise.then(...)
    .catch(function(error) {
        $A.reportError("error message here", error);
    });

catch() についての詳細は、「Mozilla Developer Network」を参照してください。

Promise で保存可能なアクションを使用しない

フレームワークは、保存可能なアクションの応答をクライアント側のキャッシュに保存します。この保存された応答によってアプリケーションのパフォーマンスが大幅に向上し、一時的にネットワークに接続されていないデバイスをオフラインで使用できるようになります。保存可能なアクションが適しているのは参照のみのアクションだけです。

保存可能なアクションのコールバックが複数回呼び出されていることがあります。この場合、初回はキャッシュされたデータが使用され、それ以降はサーバからの更新済みデータが使用されます。Promise は解決または却下を 1 回のみ行うものであるため、複数の呼び出しは Promise に適していません。