Rxjs 使用first() 和timer()

我试图每 10 秒调用一次服务,但也想仅在第一次发射时执行一些代码,这里的问题是第一个条目是重复的,代码如下:


ionViewWillEnter() {

  this.isLoading = true;

  const Obs = timer(0, 10000).pipe(

    switchMap(() => {

      return this.serviceName.someFunc();

    })

  );

  this.timerSub = Obs.subscribe();

  this.timerSub = Obs.pipe(first()).subscribe(() => {

    this.isLoading = false;

  });

}

我还注意到另一个问题,即即使我在离开页面时取消订阅,该服务仍然每 10 秒调用一次,任何帮助都会受到赞赏。


更新


我找到了一个解决方案,但它更多的是一种解决方法,基本上我所做的是在订阅上设置 setTimeout :


this.timerSub = Obs.pipe(first()).subscribe(() => {

  this.isLoading = false;

});

setTimeout(() => {

  this.timerSub = Obs.subscribe();

}, 10000);

显然,取消订阅问题也得到了解决,尽管我希望得到一些更优雅的解决方案的反馈,提前致谢。


拉丁的传说
浏览 93回答 2
2回答

叮当猫咪

Nilesh Patel 提供的答案应该可以正常工作,但我仍然想添加这个答案来分享一些您可能需要在应用程序中使用的小技巧和改进。请看一下这个Stackblitz 演示。首先要注意的是,如果您正在使用该timer运算符并且您有兴趣在它第一次发出时执行某些操作,您可以检查该运算符返回的值并查看它是否为0:我试图每 10 秒调用一次服务,但也想仅在第一次发射时执行一些代码,这里的问题是第一个条目是重复的,代码如下:ionViewWillEnter() {  this.isLoading = true;  const Obs = timer(0, 10000).pipe(    switchMap(() => {      return this.serviceName.someFunc();    })  );  this.timerSub = Obs.subscribe();  this.timerSub = Obs.pipe(first()).subscribe(() => {    this.isLoading = false;  });}我还注意到另一个问题,即即使我在离开页面时取消订阅,该服务仍然每 10 秒调用一次,任何帮助都会受到赞赏。更新我找到了一个解决方案,但它更多的是一种解决方法,基本上我所做的是在订阅上设置 setTimeout :this.timerSub = Obs.pipe(first()).subscribe(() => {  this.isLoading = false;});setTimeout(() => {  this.timerSub = Obs.subscribe();}, 10000);显然,取消订阅问题也得到了解决,尽管我希望得到一些更优雅的解决方案的反馈,提前致谢。

摇曳的蔷薇

更好的解决方案:在顶部创建变量firstSub 。ionViewWillEnter() {  this.isLoading = true;  this.timerSub = timer(0, 10000).pipe(    switchMap(() => {      return this.serviceName.someFunc();    })  );  this.firstSub = this.timerSub.pipe(first());  this.firstSub.subscribe(() => {    // only emit once(first)    this.isLoading = false;  });}在组件视图销毁之前取消订阅。ngOnDestroy(){  this.timerSub.unsubscribe();  this.firstSub.unsubscribe();}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript