読者です 読者をやめる 読者になる 読者になる

アプリカンブログ

HTML5でiOS/Androidアプリが開発できるプラットフォーム、アプリカンのブログです。

アプリカンのAPIをPromiseを使って利用する

アプリカンのAPIは基本的に関数を呼び出して、その成功時、失敗時をコールバックで受け取る形になっています。例えばQRコードやバーコードの読み取りを行う場合は次のようになります。

Barcode

captureBarcode(Function<BarcodeResult> successCallback, Function errorCallback)

実装としては次のようになります。

function captureBarcode(){
    applican.barcode.captureBarcode(captureBarcodeSuccess, captureBarcodeError);
}
function captureBarcodeSuccess(res){
    var dump = "captureBarcodeSuccess\n";
    dump += "codeData:"+res.codeData+"\n";
    document.getElementById("dumpAreaBarcode").value =dump;
}
function captureBarcodeError(e){
    var dump = "captureBarcodeError\n";
    document.getElementById("dumpAreaBarcode").value =dump;
}

captureBarcode();

コールバック方式の場合、ネストが深くなりがちなので徐々にコードが見づらくなる傾向があります。そこでPromiseに置き換えてみようというのが当記事になります。

モダンなブラウザであればPromiseが実装されているようですが、古いブラウザの実装状況が分からないので今回はkriskowal/qを使ってみます。

Promiseの基本形

Promiseを使った書き方では、まずPromiseオブジェクトを返すのが基本です。

function captureBarcode(){
  var deferred = Q.defer();
  return deferred.promise;
}

captureBarcode();

そして処理が成功した時にはdeferred.resolve、失敗した時にはdeferred.rejectを呼び出します。それぞれ、doneとfailというメソッドで受け取れます。

function captureBarcode(){
  var deferred = Q.defer();
    : 何かの処理
  if (result == "success") {
    deferred.resolve(message);
  }else{
    deferred.reject(message);
  }
  return deferred.promise;
}

captureBarcode()
.done(function(message) {
  // 成功した時の処理
})
.fail(function(message) {
  // 失敗した時の処理
});

先ほどのバーコードを読み取るAPIは次のように書き換えられます。

function captureBarcode(){
  var deferred = Q.defer();
  applican.barcode.captureBarcode(
  function(res) {
    deferred.resolve(res);
  },
  function(e) {
    deferred.reject(e);
  },
  );
  return deferred.promise;
}

captureBarcode()
.done(function(res) {
  // 成功した時の処理
})
.fail(function(e) {
  // 失敗した時の処理
});

処理を並列化したい場合

ネットワークアクセスなど一度に複数のリソースを取得することで体感速度を高速化できる可能性があります。こうした処理をコールバック方式で書くのは大変ですがPromiseの場合はシンプルです。Q.whenを使います。アプリカンでネットワークを使う場合、get関数を使います。

HTTP通信

get(String url, HTTPOptions options, object headers, Function successCallback, Function errorCallback)

2カ所から平行してデータを取得して処理を行う場合、次のように記述します。

function http_get(url) {
  var deferred = Q.defer();
  get(
    url,
    {timeout:10000},
    function (res) {
      // 成功時の処理
      deferred.resolve(res);
    },
    function (message) {
      // 失敗時の処理
      deferred.reject(message);
    }
  );
  return deferred.promise;
},

Q.when(
  http_get("http://example.com/1"),
  http_get("http://example.com/2")
).always(function(ajax1_result, ajax2_result) {
  // 変更処理の場合はdone/failではなくalwaysとしていずれかにエラーが起きた場合も対応できるようにしておくのが良いです。
});

http://example.com/1http://example.com/2 のデータ取得は平行して行われます。処理が成功か否かに関わらずすべての並行処理が終わった段階でalwaysが呼ばれますので、そこでデータをマージしたり、別な処理に渡したりすることが可能です。


JavaScriptは非同期処理が基本で、スマートフォンアプリにおいてもバックグラウンドや並行処理を活用することでユーザの体感速度を引き上げる工夫が求められます。そういった処理の中でメンテナンス性の高い、生産性の高い状態を保ち続けるというのは容易ではありません。

アプリカンはピュアなJavaScriptライブラリとしてインタフェースが提供されていますので、このように外部ライブラリを活用するのも簡単です。ぜひPromiseを覚えて開発効率を向上させてください!