场景:
我有一个每 2 秒轮询一次 URL 的服务:
export class FooDataService {
...
public provideFooData() {
const interval = Observable.interval(2000).startWith(0);
return interval
.switchMap(() => this.http.get(this.requestUrl))
.map(fooData => fooData.json())
}
}
现在我有一个组件,我想在其中显示此轮询数据:
export class FooComponent implements OnInit {
constructor(private fooDataService: FooDataService) {}
public fooData$: Observable<FooData>;
ngOnInit() {
this.fooData$ = this.fooDataService.provideFooData();
}
}
在组件模板中,我将使用异步管道来检索值并将其传递给子组件:
<foo-data-viewer [data]="fooData$ | async"></foo-data-viewer>
这种方法的问题:
像这样实现它不能用 Protractor 测试(参见我的 last question on this topic 或 this article )。所有代码都在 ngZone 内执行, Protractor 将在继续之前等待所有排队的 Action 完成。但是
Observable.interval()
将无限数量的 Action 排队,从而导致 Protractor 超时。常见的解决方法:
我最常阅读的修复方法是使用
runOutsideAngular
像这样:export class FooComponent implements OnInit, OnDestroy {
constructor(private ngZone: NgZone,
private fooDataService: FooDataService) {}
public fooData: FooData;
public fooDataSubscription: Subscription<FooData>;
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.fooDataSubscription =
this.fooDataService.provideFooData()
.subscribe(
fooData => this.ngZone.run(() => this.fooData = fooData)
);
});
}
ngOnDestroy(): void {
this.fooDataSubscription.unsubscribe();
}
}
通过在 ngZone 之外运行间隔, Protractor 在继续之前不会等待轮询完成,因此不会超时。
然而,这意味着:
async
管道,我必须手动订阅。 我的问题:
有没有办法在 ngZone 之外运行间隔时保持功能性 rxjs 风格并继续使用异步管道(或等效管道)?
我偶然发现 this github project这看起来正是我想要的,但我无法让它工作。
我需要的是一个可以像在我的场景中一样离开和重新进入区域的工作示例,而无需自己管理订阅。
最佳答案
import { Injectable } from '@angular/core';
import { interval, of, timer } from 'rxjs';
import { startWith, switchMap, delay, map, share, shareReplay } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class DataService {
private fakeRequest$ = timer(1000).pipe(map(() => new Date().getTime()))
private pollingData$ = interval(2000)
.pipe(
switchMap((index) => this.fakeRequest$),
shareReplay(1)
)
constructor() { }
public getData$() {
return this.pollingData$;
}
}
Stackblitz
关于angular - 使用异步管道轮询 Observables?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43388701/