【问题标题】:Unsubscribe from timer in rxjs取消订阅 rxjs 中的计时器
【发布时间】:2019-12-04 06:14:04
【问题描述】:

您好,我有一个计时器正在运行,就像它应该在每 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));
}

它仍然会在计时器内打印日志,例如“隐藏奖金优惠”和“呼叫计时器”。

谁能指出问题。自从我进入这个以来已经有一天了。

感谢任何帮助。

【问题讨论】:

  • 澄清一下,你想要on(30s)-off(10s)-on(30s)-off(10s)-....
  • 是的,这就是预期的行为
  • 感谢您的澄清。基于此,我创建了一个答案

标签: reactjs react-native react-redux rxjs


【解决方案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(...

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 2018-07-29
      • 2017-03-26
      • 2020-10-28
      • 2017-11-21
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多