今回はXhrManagerを使い複数のリクエストを送った場合、それらすべてが終了したことを知る方法を調べる。
XhrManager 自体にはそういった機能は無いので基本的に自前で実装する必要がありそうだ。考えられる方法としては、リクエストの状態を管理しておき(未送信 or 送信済)、すべての状態が”送信済”になるかを判断する、というのがある。
具体的な方法は2つ考えられて、一つは XhrIo の処理終了毎に条件をチェックして全部終わっていたら所定の関数を呼ぶ方法。通常はこれで十分。
もう一つは一定間隔で状態をチェックし、全部終了していれば所定の関数を呼ぶ方法。一つ目に比べると複雑になるが、処理全体のタイムアウト処理を入れることができるのがメリットとしてある。
この2番目の処理にうってつけなのが以前紹介した goog.async.ConditionalDelay。
これを使うと一定間隔[ms]で関数が呼ばれ、この関数が true を返すまでは繰り返すという動作が作れる。
今回の場合、
条件:すべてのリクエストが送信済
間隔:ポーリング間隔(500ms〜1000ms ぐらいで十分?)
前回までのサンプルに手を入れて ConditionalDelay を使った終了処理を実装してみよう。
xhrio3.html
<script> goog.require('goog.async.ConditionalDelay'); goog.require('goog.net.XhrManager'); goog.require('goog.ui.CustomButton'); goog.require('goog.ui.decorate'); </script> <script> var xhrm_ = new goog.net.XhrManager(1, {}, 1, 10, 3000); function output(msg) { var console = goog.dom.$('console'); console.innerHTML = console.innerHTML + msg + "<br/>"; } function handleResponse(e) { var xhr = e.target; output(xhr.getStatus() + " : " + xhr.getResponseText()); } function start(e) { delay.start(500, -1); btn_start.setEnabled(false); btn_cancel.setEnabled(true); for (i=0; i < 10; i++) { xhrm_.send( i, '/echo?name=' + i, 'GET', null, {}, 1, handleResponse); output('send: ' + i); } } function cancel(e) { btn_start.setEnabled(true); btn_cancel.setEnabled(false); for (i=0; i < 20; i++) { xhrm_.abort(i, true); } alert('cancel'); } var delay = new goog.async.ConditionalDelay( function() { var count = xhrm_.getOutstandingCount(); goog.dom.$('info').innerHTML = 'getOutstandingCount: ' + count; return (count == 0); }); delay.onSuccess = function() { btn_start.setEnabled(true); btn_cancel.setEnabled(false); alert('success!'); }
サンプルでは状態管理は行わず安易に XhrManagerの処理中件数(getOutstandingCount)だけで判断している。
実行してみよう。
処理中は getOutstandingCount の値が増減する。やがて終わると..
出た。
goog.async.ConditionalDelay はタイムアウト指定もできるので、複数リクエスト全体の処理時間に対してのタイムアウト処理も行うことができる。この組み合わせは、なかなか便利だ。
0 件のコメント:
コメントを投稿