2016-10-08 6 views
3

私はRxを初めて使い、Httpでトークン管理の作業をしています。私はトークンを追跡し、このトークンがすべてのアウトバウンドHTTPリクエストのヘッダーに追加されるという考えがあります。RxJs - 購読対象の件名から次の件を呼ぶ

コードはそうのようになります。観測可能な要求から返される

const request = (name, token, time) => { 
    console.log('attempt ' + name + ' with token ' + token); 
    return Rx.Observable.timer(time) 
     .do(() => { 
     console.log('sent ' + name + ' with token ' + token); 
     }) 
     .mapTo({ newToken: 'baz' }) // token baz arrives 
     .do(r => { 
     console.log('response for ' + name + ' received'); 
     }); 
}; 

const token$ = new Rx.ReplaySubject(1); 

token$.switchMap(token => request('request1', token, 0)) 
    //.do(rs => { token$.next(rs.newToken); }) // fails, causes a loop 
    .subscribe(
     // (rs) => { token$.next(rs.newToken); } // also fails with loop 
    ); 

token$.switchMap(token => request('request2', token, 1000)) 
    .subscribe(); 

// emit a token 

token$.next('bar'); 

// but how do I ensure 'request2' is sent with token 'baz' ? 

私の質問は、どのように私はbazReplaySubjectを更新することができますか?

私はそうのようrequest1doからnextを呼び出してみました:

token.switchMap(token => request('request1', token, 0)) 
    .do(rs => { token.next(rs.newToken); }) 
    .subscribe(); 

しかし、これはループにそれを送り、request1がトークンbazで繰り返されます。件名のnextdoから購読されたObservableでこのように呼び出すことはできますか?私はそれがいくつかのRx契約や何かに違反しているのだろうかと思っています。

私はまた、このようrequest1を試してみました:

token.switchMap(token => request('request1', token, 0)) 
    .subscribe(rs => { token.next(rs.newToken); }); 

しかし、同じループが発生します。おそらく私はnextを私がswitchMapである事に呼んでいるからでしょうか?

どのように私はこれを動作させることができますか?ありがとう!その後、再利用されるべきである、私はあなたが右のこのmap関数は、実際にいくつかの外部コールを行うと、トークンを返すことになっている理解していれば

jsbin here

+0

あなたは明確にしてくださいすることはできます(また、私たちはswitchの有益な行動を失うことになる。RxJsにはswitchScanはありません)。トークンはサーバーによって割り当てられていますか?そうであれば、なぜそれを「foo」に変更してから「bar」に変更しますか?新しいトークンを手に入れたらすぐに行動しますか? – Meir

+0

トークンはサーバーによって返されます。はい。私はテストのために上記の 'foo'と' bar'トークンを追加しました。考え方は、request1はトークン 'bar'(これはそうです)を持っていて、request2はサーバによって返されたトークン' baz'を持っていなければなりません(現在はありません)。私は 'do'関数で' next(rs.newToken) 'を呼び出し、 'subscribe'コールバックでもこれを試みていました。あなたがjsbinを見ると、それがどうして失敗するか見ることができます。 – ghostypants

+0

コードを少しきれいにして 'foo'ナンセンスを削除しました。お返事をありがとうございます! – ghostypants

答えて

0

OK?そして、return { newToken: 'baz' };はちょうど嘲笑された結果です。

token.next('bar')は、replaySubjectに新しいトークンを追加するだけでなく、新しい要求も発生させるという問題があります。

newRequestSubjecttokenSubjectから分割します。そうすれば、新しいトークンを発射することなく新しいトークンをプッシュすることができます。これは、すでに気付いたように無限ループに終わることになります。

その後、requestSubjectを準備するためにnewRequestSubject.withLatestFrom(tokenSubject).switchMap(request).subscribe()を使用して要求をプッシュするnewRequestSubject.next(200, 'request1')を呼び出すことができます。

tokenSubjectreplaySubjectbehaviorSubjectに置き換えることもできるので、作成時に最初のトークンを渡すことができます。

requestの中には、tokenSubject.next()を呼び出してトークンを更新できます。

副題として、件名を一括して除外することは、たとえばmergeScanなど、以前のリクエストの結果を次のものに送ることができますすぐに理解するのが少し難しい。

newRequestSubject.mergeScan(request, initialToken); 

+0

あなたの答えをありがとう!私は間違いなく 'mergeScan'を調査します。私はコアの問題に気を散らしていたと感じているので、間隔のものを削除するように質問を更新しました。現在、ランダムな間隔を使用しています。 – ghostypants

+0

OKこの[jsbin](http://jsbin.com/huwita/44/edit?js,console)で提案し巻いたものに似たものを試しました。私は2つの科目を使用していますが、動作するようです。ありがとう! – ghostypants

関連する問題