我从API服务获得交易,条件是交易状态为“待定”,继续重新加载和订阅交易,直到交易状态为“已完成”或“已拒绝”。我的代码只能在第一次工作,然后下次访问时,页面是空白的,但数据仍然在控制台中运行,即使我取消订阅它。
这是我的代码:
export class TransactionSummaryComponent implements OnInit, OnDestroy {
transaction: Models.Transaction = <Models.Transaction>{};
cancelling: boolean = false;
goToPayment: boolean = false;
private dataRefreshSub: Subscription;
private subscribeToDataSub: Subscription;
private timer: Observable<any>;
constructor(
private route: ActivatedRoute,
private router: Router,
private apiService: ApiService,
private zone: NgZone,
@Inject(PLATFORM_ID) private platformId: Object) { }
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
this.getTransaction();
}
}
getTransaction() {
this.route.paramMap
.switchMap((params: ParamMap) => this.apiService.getTransaction(params.get('id')))
.subscribe((transaction: Models.Transaction) => {
this.transaction = transaction;
if (this.transaction.status === 'Pending') {
this.refreshData();
}
});
}
refreshData() {
this.dataRefreshSub = this.route.paramMap
.switchMap((params: ParamMap) => this.apiService.getTransaction(params.get('id')))
.subscribe((transaction: Models.Transaction) => {
this.transaction = transaction;
this.subscribeToData();
});
}
subscribeToData() {
this.zone.runOutsideAngular(() => {
NgZone.assertNotInAngularZone();
this.timer = Observable.timer(1, 5000);
this.subscribeToDataSub = this.timer
.subscribe(() => {
this.refreshData();
});
});
}
ngOnDestroy() {
if (this.dataRefreshSub !== undefined) {
this.dataRefreshSub.unsubscribe();
}
if (this.subscribeToDataSub !== undefined) {
this.subscribeToDataSub.unsubscribe();
}
}
}
答案 0 :(得分:1)
我无法提出不使用副作用的解决方案,但我认为它可能对您有所帮助。 Rxjs有一个retry()
运算符,它会在抛出时重新运行订阅。所以我会做这样的事情:
getTransaction() {
this.route.paramMap
.switchMap((params: ParamMap) => this.apiService
.getTransaction(params.get('id'))
.do(transaction => this.transaction = transaction) // Bad side effect here, I'm not sure how can this be cleaned out.
.map(transaction => {
if(transaction.status === 'Pending') {
throw 'Pending';
}
return transaction;
})
// use .retry(N) to retry at most N times. This will infinitely retry
.retryWhen(errors => errors)
)
.subscribe((transaction: Models.Transaction) => {
// Here transaction will be 'Completed' or 'Rejected'
});
}
有了这个,您可以理论上删除所有其他订阅。