2016-04-19 5 views
1

私は報告書を受け取るサービスを持っています:

ReportsResource.getActiveUsers()これは$httpを使用して約束を返します。

私は、このようにそれを使用します。

var request = ReportsResource.getActiveUsers(); 

request.then(populateActiveUsersTable, handleError); 

しかし、漁獲量は、アクティブなユーザーがバックエンドでレポートを取得するための要求は、数秒から、30 +分にどこでも取ることができることです。

  • あなたが要求していないキャッシュされたレポートが利用可能であることを確認した場合には、それはレポートを生成し、その要求は、その要求のために(再び、2秒または30分かもしれない)データを待ちます。

  • レポートを作成していて、現在レポートが生成されている場合は、すぐにレポートが準備完了ではない旨の応答が返されます。どの時点でポーリングを続けて、レポートが準備完了しているかを確認できます。

  • レポートが準備完了(キャッシュ)されている場合は、レポートデータとともに即座に応答を返します。私は必要なもの

は10秒まで待機し、タイムアウトにリクエストをラップで、その後、応答が完了するまでに長い10秒以上かかる、と報告書は準備ができているかどうか尋ねるためにポーリングにサーバーを起動する場合は中止しますまだ。しかし、要求が10秒未満で解決された場合、タイムアウトをキャンセルし、通常どおりに約束を実行する必要があります。

これはどのように処理するかわかりません。

答えて

0

timeoutではなく、WebSocketを使用する方が良いと思います。 WebSocketを使用すると、サーバーから送信された更新/変更があるたびに実行する必要がある機能を登録するだけで済みます。ポーリングを維持する代わりに、WebSocketはリソースを少なくし、効率を上げます。しかし、バックエンドでは少しの作業が必要です。

実装は、さまざまなバックエンド言語を使用します。おそらく、バックエンドの人々(またはあなた自身)と話をする必要があります。これはあなたにいくつかのアイデアを与えることができるといいですね。

===編集===

あなたがtimeoutまたはintervalのようなサービスを利用したい場合は、以下のコードは助けるべきである:

//inside your controller 
var pollingPromise = $q.defer(); //used to controll the fired $http request 

var pollingActiveUsers = function() { 

    ReportsResource.getActiveUsers(pollingPromise).then(function(data){ 
     //stop polling 
     $interval.cancel(pollingProcess); 
     //set to the controller's scope 
     $scope.activeUsers = data; 
     //populate the activeUsersTable 
     populateActiveUsersTable(); 
    }); 
}; 

//init the first request 
pollingActiveUsers(); 

//polling for every 10secs 
var pollingProcess = $interval(function() { 
    //resolve the previous polling request which mean cancel the previous $http request if it waits longer than 10 secs 
    pollingPromise.resolve(); 

    //start another polling, a new pollingPromise is required 
    pollingPromise = $q.defer(); 

    pollingActiveUsers(); 
}, 10000); 

//In your service ReportsResource 
//you have to make another change function getActiveUsers() to make this work, you have to pass the pollingPromise to the $http method, so you can cancel the $http request: 
var function getActiveUsers = function(promiseObj) { 
    return $http.get('someUrl', { timeout: promiseObj }); 
}; 

ほとんどの懸念が行われます:

  1. すでに$ httpリクエストが解約された場合は、10秒以上かかると解消/解決されます。そのため、pollingPromiseが必要です。さらに詳しい情報は:cancel unresolved promise
  2. 新しい$ httpリクエストは10秒ごとに発行され、$intervalはこの問題を解決し、$interval.cancel()関数はこの間隔を停止します。
  3. アプリに適用したときにコードを変更する必要があります

所望のデータを受信したときにポーリングがすぐに停止する必要があります。

+0

はい、これは理想的ですが、残念なことに、この特定の作業の範囲では実行できないアーキテクチャ上の実装です。私たちはロードマップを持っていますが、いくつかのノックオン効果などがあるBEの非同期処理の変更が必要です。 – AgmLauncher

0

角度の$qと一緒に$timeoutを使用します。 $q.defer()で遅延を作成し、タイムアウトを指定してリクエストを作成し、その結果をthenハンドラに転送して遅延を解決します。要求がタイムアウトした場合は、ポーリングを開始します。直ちに延期の約束を返す。

var d = $q.defer() // defered for the final result 

function poll() { 
    $http({...}).then(//poll request 
     function(res) { 
      if (ready(res)) 
       d.resolve(res) 
      else { 
       $timeout(poll, 10000) 
      } 
     }, 
     function(err) { 
      d.reject(err) 
     }) 
} 

$http({ timeout: 10000, ... }).then(
    function(res) { 
     d.resolve(res) 
    }, // return result directly 
    function(err) { // error or timeout 
     if (realError(err)) // check if real error 
      d.reject(err) 
     else { //timeout 
      $timeout(poll, 10000) 
     } 
    }) 
return d.promise 

あなたは任意にしばしば待つか、キャッシュされた結果を得ることがthenを呼び出して返された約束を再利用することができます。

関連する問題