2017-09-21 11 views
0

私のAngularアプリでは、私は通知の作業をしています。最新のユーザーの通知を呼び出すREST APIがあります。このAPIを数分で呼び出す必要があります。実際にユーザーがリアルタイムで通知を受け取ることは重要ではないため(おそらくそれほど速くは表示されません)しかし、クライアント側に通知をリフレッシュするアイデアは次です:間隔でRxJSポーリングを手動で呼び出す場合

  • 開始ユーザがログイン通知をリフレッシュすると - ユーザーがアプリを離れる場合は、ここで数分
    • にAPIをリフレッシュ開始する最初のマニュアルコールがあります開いているか、アプリをナビゲートしているだけです。その後、タイマーを変更せずに残りの時間を待ちます。
    • 通知に関するアクションを実行できるサブページを開き、通知をリフレッシュしてリセットすると、
  • 更新通知ログアウト

まで、私はすでに述べたプロシージャのコードを働いてきたが、私はそれは私が必要なもののために正しいだと何とかわかりませんよ。ここで呼び出しを実行するためのコードである(手動チェックのためには、ちょうど件名があって、そこに観察へのサブスクリプションでチェックストップ用 - 以下、実際に分離されているコードは、しかし、こちらの読みやすさの一つの場所にある):

// Subject for manual triggering 
this.checkFeed = new Subject<void>(); 

// Call for refresh in own method 
this.checkFeed.next(); 

// Waiting for manual refresh or triggering it on some interval after it was last triggered 
this.feedSub = this.checkFeed.asObservable() 
     .switchMap(() => Observable.timer(0, this.interval)) 
     .mergeMap(() => this.fetchChanges()) 
     .distinctUntilChanged(this.compareFeed) 
     .subscribe(res => this.notify(res)); 

// Unsubscription when logging out 
if (this.feedSub) this.feedSub.unsubscribe(); 

私が一番不確かな部分は.switchMap(() => Observable.timer(0, this.interval))です。すぐに開始するには0が必要です(これは大丈夫ですが、まだまったく正しいとは限りません)。だから私が説明したことを達成するためのより良い方法はありますか?

別の観測値から通知を確認する方法 - 私はどの演算子を使うべきですか?私が述べたように、私は、件名の次の自身の方法でこのように呼んでいます

refreshFeed(): void { 
    this.checkFeed.next(); 
} 

を(通知をリフレッシュする必要があるアクション)を実行するいくつかの他の観察可能があるときに私はこの1つを呼び出す必要があります。 voidメソッドを呼び出す正しい方法は、他の観測対象にAPIからの応答がある場合です。私は次のようなことを考えていました。

someActionThatCanChangeNotifications(): Observable<any> { 
    return this.api.get('path/to/endpoint') 
    .do(() => this.feedService.refreshFeed()); 
} 

これはいいですか、それとも良い方法ですか?

ありがとうございました!

答えて

0

だから、基本的にあなたは2つの観測可能性を持っています。手動で呼び出す

ワン:

this.checkFeed 

との間隔を(のはintervalObsをCALLITてみましょう):あなたはこのようにそれを見た場合

this.intervalObs = Observable.timer(0, this.interval); 

はeasyest方法はyou'r 2つのソースをマージすることですあなたが望むものを何でもしてください。

var mergedSource = Observable.merge(
    this.checkFeed, 
    this.intervalObs) 

subscription = mergedSource.subscribe(this.fetchChanges()); 

これ以上の操作を行う必要があるかもしれませんが、これはわかりやすい方法です。

あなたは私はあなたが非常に多く、「正しく」それをやった見ることができるものからhttps://plnkr.co/edit/n4nNFEMa4YOh2KSjDpSJ?p=preview

+0

インターバルを5秒(プランナー内)に設定してからインターバルの途中でクリックすると(イベントが発生するまで2〜3秒が残っているため)、オブザーバブルのマージはうまくいかない5秒にリセットされるのではなく、残りの時間(前述のように2または3秒)後に放出されます。 – user1257255

0

arroundのプレーするために何かをしたい場合は、この作業plunkerを試すことができます。一般的にプログラミングと同様に、単一の問題に対する多くの(そして正しい)解決策が存在する。個人的には、私はこれと同じやり方をしています。

私はあなたがあまりにも言及した二つの点でいくつかの論評与えることができます:最初の値の前にカスタムタイムアウトと

.switchMap(() => Observable.timer(0, this.interval))

Observable.timerほとんどObservable.intervalを。 Observable.timer(0, this.interval)が正しい使用法です。

代わりにObservable.just(0).concat(Observable.interval(this.interval))を指定すると、すぐに値が返され、間隔が開始されます。私はあなたが置く方法を好む;私はそれがあなたの意図を明確に述べていると思います: "0ミリ秒後に値を作り、その後にはthis.intervalの間隔"を作ります。

.do(() => this.feedService.refreshFeed())

私は、これはそれを行うための、完全に正しい方法であると思います。 doは、副作用を意味します。何が起こっているの外側は観察可能です。

私は言うことができる、私はsomeActionThatCanChangeNotificationsフィードのリフレッシュを開始するとは思わない。関数がobservableを返すとき、私は副作用のないobservableを返すことを期待します。しかし、私たちが完全でない世界に住んでいるので、私たちはいつも私たちが望むものを持つことはできません。

.do(() => this.feedService.refreshFeed())を覚えているすべてのサブスクライバを期待することはできません。代わりに、関数のドキュメントコメントに通知を追加します。「注:返された観測結果は、次のすべての信号でフィードを更新します。その種の

関連する問題