[Salesforce]アップデートの前後の値比較

アップデートの前後の値比較

trigger UpdateTesObject on TesObject__c (before update) {
    for(TesObject__c tesObject : Trigger.New) {
        TesObject__c oldtesObject = Trigger.oldMap.get(tesObject.id);
        if (tesObject.TestStatus__c != oldtesObject.TestStatus__c ) {
            tesObject.Is_TestUpdated__c = true;
        }
    }
}

[Salesforce]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 に適していません。

[Salesforce]JavaScript Remoting の制限および考慮事項

JavaScript Remoting の制限および考慮事項

JavaScript Remoting の制限および考慮事項

JavaScript Remoting はリソース制限の対象ではありませんが、機能自体に制限があります。

JavaScript Remoting は、Salesforce のサービス制限を回避するための手段ではありません。JavaScript Remoting コールには、API 制限は適用されませんが、JavaScript Remoting を使用する Visualforce ページには、すべての標準 Visualforce の制限が適用されます。

デフォルトでは、リモートコールの応答は、30 秒以内に返される必要があります。これを超えると、コールはタイムアウトになります。要求の完了にこれ以上の時間を必要とする場合は、長いタイムアウトを 120 秒以内で設定します。 リモートコールの応答の最大サイズは 15 MB です。JavaScript Remoting コードがこの制限を超える場合は、次のように対応できます。

  • 各要求の応答サイズを削減する。必要なデータのみを返します。
  • 大量データの取得を、小さなチャンクを返す複数の要求に分割する。
  • バッチ要求の使用頻度を上げ、個々のバッチサイズを削減する。
  • バッチ以外の要求を使用する。Remoting 要求の設定ブロックで { buffer: false } と設定します。

[Reference url]Javascript非同期promise

Javascript非同期promise

// 1. `new Promise()` して新しい `Promise` オブジェクトを作成
const p = new Promise((resolve, reject) => {
  // 3. 非同期処理実行
  setTimeout(() => {
    // 4. 完了時に `resolve()` を実行
    const result = 123;
    resolve(result);
  }, 1000);
});
 
// 2. `Promise` オブジェクトに `then()` でコールバックを登録
p.then((result) => {
  // 5. `resolve()` に与えた情報を伴ってコールバック実行
  console.log(result)
});

[Reference url]Javascript Remoting で Async/Await 例

Javascript Remoting で Async/Await 例

https://qiita.com/hrk623/items/30b89575c1478eeced37

<apex:page controller="AsyncAwaitSampleController">
    <script>
    (async () => {
      let accountList = await getAccountList().catch(err => {console.error(err.message); });
      if (accountList) { // エラー時は undefined となるので注意
        console.log(accountList);
      }
    })();

    const REMOTEACTION_OPTIONS = {buffer: true, escape: true, timeout: 120000};
    function getAccountList() {
      return new Promise((resolve, reject) => {
        Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.AsyncAwaitSampleController.getAccountList}',
          (result, event) => {
            if (event.status) resolve(result);
            else reject(event);
        }, this.REMOTEACTION_OPTIONS); // アロー関数を使う場合は this を忘れずに
      });
    }
    </script>
</apex:page>
public class AsyncAwaitSampleController {
    @RemoteAction
    public static List<Account> getAccountList() {
        return [SELECT Id, Name FROM Account];
    }
}