2016-11-10 8 views
1

私はrxjsオブザーバブルを使用してHTTP経由でアクセス可能なデバイスと通信しています。 HTTPコールは、デバイスが完全にオンラインになる前に開始されるため、最初にいくつかのコールが失敗する可能性があります。ある時点で、デバイスはオンラインになり、更新が開始され、進行状況が定期的にポーリングされます。更新の終わりに、デバイスは再起動する必要があり、その後、別のURLで進捗状況を提供します。少なくとも1つの成功した応答が少なくとも1つ続いた後、別の観測可能なものにスワップエラーが発生しました

今私はrxjsでこの動作をマッピングする:

successfulCall: boolean = false; 

testGet() { 
    return Observable.timer(0, 1000) 
     .concatMap(() => this.http.get(this.url)) 
     .map(response => { 
     let result: string = String.fromCharCode.apply(null, new Uint16Array(response.arrayBuffer())); 
     this.successfulCall = true; 
     return result; 
     }) 
     .timeout(2000) 
     .retryWhen(errors => { 

     if (this.successfulCall) { 
      return Observable.throw("offline"); 
     } 
     else { 
      return errors.delay(2000); 
     } 

     }) 
     .onErrorResumeNext(this.observableTwo); 

私の考えは、その後、他の観察可能なを選ぶことができますスイッチとしてretryWhenを使用することです。しかし、2番目の観測は開始されず、最初の観測のみが呼び出されます。デバイスのステータス(オンラインまたはオフライン)に応じて、私はタイムアウトまたは有効な回答を受け取り、通話は続行されます。私はまた、通常の制御フローの例外は非常に良い考えではないことを知っています。

問題の説明が複雑になる可能性があるので、私の考えを視覚化するために少しのフローチャートを作った。

wasSuccessfulがfalseで初期化する必要があり、観察可能な結果の処理は、アプローチは完全に大丈夫です。また

Flowchart of Observable

(より良い/多分きれい)他に示されていない、私はちょうど解決したいです問題と私のapprochを主張する必要はありません。

+0

+1。しかしここでは、入力ストリームと出力ストリームの関係がはっきりとわかるように、大理石図を作成するのが最良です。あなたの現在のダイアグラムは、タイミング情報(ポーリング)を失ってしまいます。 – user3743222

答えて

0

リモートデバイスがオンラインになるまでポーリングし、最初の起動が成功した後、アップデートプロセスを続行した後、オフラインになり、再度ポーリングを開始します。図フローの

// mock implementation of polling until succes 
 
var attempts = 0; 
 
function startUp() { 
 
    attempts++; 
 
    if(attempts < 10) { 
 
    return Rx.Observable.throw(new Error('NOT BOOTED YET')); 
 
    } 
 
    attempts = 0; 
 
    return Rx.Observable.of('remote device online'); 
 
} 
 

 
const bootupPollingSource = Rx.Observable.of('') 
 
    .concatMap(_ => 
 
    Rx.Observable.defer(() => startUp()) 
 
    .do(null, err => console.log('[debug] bootup err:' + err.message)) 
 
    .retryWhen(attempts => attempts.delay(100)) 
 
); 
 

 
const regularOperationsSource = Rx.Observable.from(['starting update','...','...']) 
 
    .concat(Rx.Observable.throw(new Error('device is rebooting'))) 
 
    .catch(err => bootupPollingSource) 
 

 
bootupPollingSource 
 
    .concat(regularOperationsSource) 
 
    .subscribe(console.log, console.log,() => console.log('completed'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>

関連する問題