2017-07-12 23 views
2

this.route.paramsが破棄され、this.subが登録解除された後、​​はログを記録し続けます。これは私の直感に反して、1つのサブスクリプションでは、契約解除後にすべてが停止するはずです。ここで何が起きているのですか&それに対処する最も良い方法は何ですか? takeUntilを追加するか、concatMap以外のものを使用すべきですか? (私は新しい写真のポーリングよ)RXJSで観測可能な内部観測オブザーバブルの受信可

constructor(private authService:AuthService, 
      private route:ActivatedRoute, 
      private router:Router, 
      private photosApi:PhotosApi) { 
} 

ngOnInit() { 
    this.sub = this.route.params 
     .switchMap(()=>{ 
      console.log('switchmap Ruun') 
      return Observable.interval(2000).startWith(0).concatMap(()=>{ 
       console.log('interval run') 
       return this.photosApi.apiPhotosGet(this.authService.getAuth(), 0, 40) 
      }) 
     }) 
     .subscribe((data:PagedResultPatientPhotoModel) => { 
       this.processPhotos(data) 
      }).add(()=>console.log('unsubscribe happened')) 

編集:私はそれをきれいにするために書き換えてみました、それは最初の呼び出しの後に動作を停止した理由を、 concatMapと、次は、唯一の呼び出しが、私はわからないん

this.intervalSub = Observable.interval(3000).startWith(0).concatMap(()=>{ 
     console.log('getting photos interval', this.route.params) 
     return this.route.params.switchMap(()=>{ 
      console.log('getting photos') 
      return this.photosApi.apiPhotosGet(this.authService.getAuth(), 0, 40) 
     }) 
    }).subscribe((data:PagedResultPatientPhotoModel) => { 
       this.processPhotos(data) 
      }).add(()=>console.log('unsubscribe happened')) 

とswitchMapで次がそうでなければ、彼らはお互いをキャンセルする限り、API呼び出しが速く3000よりも実行することができますように動作します

this.intervalSub = Observable.interval(3000).startWith(0).switchMap(()=>{ 
     console.log('getting photos interval', this.route.params) 
     return this.route.params.switchMap(()=>{ 
      console.log('getting photos') 
      return this.photosApi.apiPhotosGet(this.authService.getAuth(), 0, 40) 
     }) 
    }).subscribe((data:PagedResultPatientPhotoModel) => { 
       this.processPhotos(data) 
      }).add(()=>console.log('unsubscribe happened')) 

私はなぜSWIのように好奇心が強いですtchMap(とmergemap)は毎回動作しましたが、concatMapは一度しか動作しませんでしたが、RXJSのバグのようです

私はmergeMapを使うことに決めました。要求が間違っているしばしば、そしてもしそうなら、それは数秒後にそれ自身を修正するでしょう。

+0

https://stackoverflow.com/questions/35765322/angular2-switchmap-not-canceling-previous-http-calls - switchmapは、同じ基本ストリーム内のリクエストのみをキャンセルできるように見えます。 - 内側に伝播しません。 –

答えて

1

問題はswitchMapではありません。これは期待どおりの動作です。

const source = new Rx.Subject(); 
 

 
const subscription = source 
 
    .switchMap(() => { 
 
    console.log('> switchmap'); 
 
    return Rx.Observable.interval(500); 
 
    }) 
 
    .subscribe((value) => console.log(value)); 
 

 
source.next(1); 
 
setTimeout(() => source.next(2), 2000); 
 

 
setTimeout(() => { 
 
    console.log('> unsubscribe'); 
 
    subscription.unsubscribe(); 
 
}, 5000);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

あなたの問題は、サブスクリプションのaddメソッドの呼び出しである:構成に観察への加入が解除されたときに次のコードでは、観察可能なインナーintervalが解除されます。それは追加のサブスクリプションを作成し、subに割り当てられたサブスクリプションです。

追加のサブスクリプションを追加した最初のサブスクリプションは、変数に割り当てられておらず、サブスクライブされません。そして、それはintervalが引き続き実行されていることを確認するサブスクリプションです。 - しかし、その逆はない

const source = new Rx.Subject(); 
 

 
const subscription1 = source 
 
    .switchMap(() => { 
 
    console.log('> switchmap'); 
 
    return Rx.Observable.interval(500); 
 
    }) 
 
    .subscribe((value) => console.log(value)); 
 

 
const subscription2 = subscription1.add(() => console.log('> unsubscribed')); 
 

 
source.next(1); 
 
setTimeout(() => source.next(2), 2000); 
 

 
setTimeout(() => { 
 
    console.log('> unsubscribe 2'); 
 
    subscription2.unsubscribe(); 
 
}, 5000); 
 
setTimeout(() => { 
 
    console.log('> unsubscribe 1'); 
 
    subscription1.unsubscribe(); 
 
}, 6000);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

subscription1unsubscribeを呼び出すとsubscription2解除、あまりにも参照すること。

次のコードは、問題を示しています。

+0

Ahh 、右、私は追加したことを忘れて.add、と気づいていない.addは別のサブスクリプションを返しました。混乱、それをクリアするためのおかげで –

関連する問題