退订rxjs中的计时器

时间:2019-12-04 06:14:04

标签: reactjs react-native react-redux rxjs

嗨,我有一个计时器正在运行,就像它应该每隔10秒显示一个组件30秒。我的代码是这样的

import { timer } from "rxjs";

componentWillReceiveProps(nextProps, nextState) {
    console.log("RECEIVED PROPS");
    if (this.props.venuesBonusOfferDuration === 0) {
      this.subscribe.unsubscribe();
    }

    this.firstTimerSubscription;
    this.secondTimerSubscription;
    // if (this.state.isMounted) {
    if (
      nextProps.showBonusObj &&
      (!nextProps.exitVenue.exitVenueSuccess || nextProps.enterVenues)
    ) {
      // console.log("isMounted" + this.state.isMounted);

      //if (this.state.isMounted) {
      let milliseconds = nextProps.venuesBonusOfferDuration * 1000;
      this.source = timer(milliseconds);
      this.firstTimerSubscription = this.source.subscribe(val => {
        console.log("hiding bonus offer");
        this.firstTimerSubscription.unsubscribe();
        this.props.hideBonusOffer();
        this.secondTimerSubscription = bonusApiTimer.subscribe(val => {
          console.log("caling timer" + val);

          this.props.getVenuesBonusOffer(
            this.props.venues.venues.id,
            this.props.uid,
            this.props.accessToken
          );
        });
      });
      //}
    } else {
      try {
        if (this.secondTimerSubscription != undefined) {
          this.secondTimerSubscription.unsubscribe();
          console.log("secondTimer UNSUBSCRIBED");
        }
        if (this.firstTimerSubscription != undefined) {
          this.firstTimerSubscription.unsubscribe();
          console.log("firstTimer UNSUBSCRIBED");
        }
      } catch (error) {
        console.log(
          "error when removing bonusoffer timer" + JSON.stringify(error)
        );
      }
      //}
    }
  }

`

问题是,如果我尝试取消订阅此* this.firstTimerSubscription *和 this.secondTimerSubscription

try {
  if (this.secondTimerSubscription != undefined) {
    this.secondTimerSubscription.unsubscribe();
    console.log("secondTimerunmount UNSUBSCRIBED");
  }
  if (this.firstTimerSubscription != undefined) {
    this.firstTimerSubscription.unsubscribe();
    console.log("firstTimerunmount UNSUBSCRIBED");
  }
} catch (error) {
  console.log("error bonusoffer timer" + JSON.stringify(error));
}

它仍在计时器内打印日志,例如“隐藏奖励报价”和“呼叫计时器”。

有人可以指出这个问题吗?从今天开始已经有一天了。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

问题是您多次订阅(组件接收到道具时)并重新分配对firstTimerSubscriptionsecondTimerSubscription引用的最新订阅。但是这样做,订阅并不会神奇地消失。要了解其工作原理,here is a demo

const source = timer(1000, 1000);

let subscribe;
subscribe = source.subscribe(val => console.log(val));
subscribe = source.subscribe(val => console.log(val));

setTimeout(() => {
  subscribe.unsubscribe();
}, 2000)

即使您已取消订阅,第一个订阅也会不断发出。问题是您丢失了对其的引用,因此您现在不能退订。

一个简单的解决方法是检查您是否已经订阅,如果要取消订阅,请在订阅之前

this.firstTimerSubscription ? this.firstTimerSubscription.unsubscribe: false;
this.firstTimerSubscription = this.source.subscribe(...

答案 1 :(得分:1)

我不会再使用计时器。只需间隔10秒即可。该间隔发出迭代次数1, 2, 3....。您可以在该刻度上使用取模运算符。以下示例代码(例如,间隔1秒)在控制台中打印truefalsetrue之后,需要3秒才能显示falsefalse之后,需要1秒才能显示true

interval(1000).pipe(
  map(tick => tick % 4 !== 0),
  distinctUntilChanged(),
).subscribe(x => console.log(x));