Outsystemsで非同期処理を実装する方法(Promiseを使う方法)


Outsystemsで非同期処理を実装する方法という記事にいくつかの非同期処理方法が書かれていますが、その別の方法の紹介です。

対象はReactive Web Appです。Mobileでも使えますが、Traditional Webは対象外。

サンプル

Forgeコンポーネント:https://www.outsystems.com/forge/Component_Overview.aspx?ProjectId=7086
Promise Screenを参照してください。

環境

Personal Environment(Version 11.0.606.0)
Service Studio(Version 11.6.18)

概要

Promiseを使います。
PromiseはOutSystems独自の概念ではありません。Qiitaに普通のJavaScriptでの紹介がありました。
今更だけどPromise入門

OutSystemsにおけるPromiseについてのドキュメント:
Defining Asynchronous JavaScript Code

OutSystemsが標準提供する\$resolve/$rejectをJavaScript Elementに書くことで、そのClient Actionは非同期Actionになります(ブラウザに出力されるJavaScriptコードがPromiseで囲まれる)。

非同期Client Actionの例

JavaScript Elementを配置し、JavaScriptの出力をActionの出力パラメータに渡します。

JavaScript Elementの内容:

  • 同じModuleに用意したREST APIをJavaScriptの機能で取得
    • REST API内ではForgeのSleepを使って強制的に遅くすることで非同期処理の動きを確認
  • JavaScript ElementにOutput Parameter Result(Text型)を設定し、通信終了後に、その内容を設定
  • 処理の最後(通信終了後のコールバックの最後)で$resolveを呼ぶのが重要。これで呼び出し側に非同期処理の終了を知らせている
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
        $parameters.Result = xmlHttp.responseText;
        $resolve();  // ここをコメントアウトすると、このActionの呼び出しはRESTの終了を待たずに終わる
    }
}
xmlHttp.open("GET", "/HousesoftSampleReactive/rest/Promise/LongRunninAPI", true);
xmlHttp.send(null);

非同期処理を実際に呼ぶ

Client Actionから非同期処理のClient Actionを呼び出すことができます。
この場合、呼び出されたClient Actionで$resolveを実行したタイミングで呼び出し側に制御が戻ります。

また、JavaScriptを使って非同期処理のClient Actionを呼び出すこともできます。

$actions.LongClientAction().then(function(result) {
  $parameters.Out1 = result.Out1;
  $resolve();  // ここをコメントアウトすると、処理がLongClientActionの終了を待たずに終わる
});

$actions.()の呼び出しで非同期のClient ActionをClient Actionから実行しています。
実行したClient Actionからは、Promiseオブジェクトが返ってくるため、そのオブジェクトに対して、then関数を実行しています。

このthen関数は、コールバック関数を引数にとり、Promiseが返ってきた(呼び出し先で$resolveされた)タイミングでそのコールバック関数が実行されます(コールバック関数の引数オブジェクトには、呼び出し先Client Actionの出力パラメータが設定されている)。

エラー処理

エラー発生時は、エラー内容をOutput Parameterに詰めて返すか、$resolveの代わりに$rejectを呼ぶようにします。
使い方は、上のリンク先を参照してください。