嗨,我有一个计时器正在运行,就像它应该每隔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));
}
它仍在计时器内打印日志,例如“隐藏奖励报价”和“呼叫计时器”。
有人可以指出这个问题吗?从今天开始已经有一天了。
感谢您的帮助。
答案 0 :(得分:1)
问题是您多次订阅(组件接收到道具时)并重新分配对firstTimerSubscription
或secondTimerSubscription
引用的最新订阅。但是这样做,订阅并不会神奇地消失。要了解其工作原理,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秒)在控制台中打印true
和false
。 true
之后,需要3秒才能显示false
。 false
之后,需要1秒才能显示true
。
interval(1000).pipe(
map(tick => tick % 4 !== 0),
distinctUntilChanged(),
).subscribe(x => console.log(x));