我正在尝试使用rxjs和angular创建连续轮询。以下是我的要求的实现。
我的app.component模板具有例如2个或更多组件(相同的组件)。
<widget ticker='BTC'></widget>
<widget ticker='ETH'></widget>
在widget.component中,我想从API获取数据以用代码信息填充窗口小部件,但目标是收集所有代码并仅进行一次调用,例如(api / crypto / BTC,ETH)和将数据返回给所有小部件(在这种情况下为2)。每个小部件都会从响应中读取数据,并保持每分钟获取一次。
响应示例:
{ BTC: { name: 'Bitcoin', price: 7000 }, ETH: { name: 'Etherium', price: 200 }}
我的小部件组件:
export class widgetComponent implements OnInit, OnDestroy {
@Input() ticker: any;
subscription: any;
constructor(
private cryptoService: CryptoService
) { }
ngOnInit() {
this.subscription = this.cryptoService
.setupSymbol(this.ticker)
.subscribe(data => {
this.info = data[this.ticker];
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
我的服务:
@Injectable({
providedIn: 'root'
})
export class CryptoService {
tickers: any = '';
polledBitcoin$: Observable<number>;
load$ = new BehaviorSubject('');
constructor(
private http: HttpClient
) { }
bitcoin$ = this.http.get(`api/crypto/${this.tickers}`);
whenToRefresh$ = of('').pipe(
delay(1000),
tap(_ => this.load$.next('')),
skip(1),
);
poll$ = concat(this.bitcoin$, this.whenToRefresh$);
setupTicker(ticker) {
this.tickers += ticker + ',' ;
return this.load$.pipe(
concatMap(_ => this.poll$),
share()
);
}
我的代码无法正常运行。每个窗口小部件都对代码进行自己的API调用。 但是我只想让一个呼叫收集全部完成,并通过所有小部件共享数据请求。
不可能用rxjs在包含所有代码的一个数组上进行流处理,例如['BTC','ETH],然后开始轮询吗?轮询应等待,直到所有小部件都完成setupTicker。
有人打电话帮助吗?预先感谢。
答案 0 :(得分:1)
具有代码对象,每次添加新符号时,该对象都会跟踪有多少小部件正在追踪每个符号。
@Injectable({
providedIn: 'root'
})
export class CryptoService {
private tickers: { [ticker]: number } = {};
private subscription: Subscription;
tickers$ = new BehaviorSubject<{ [ticker]: { name: string, price: number } }>(undefined);
constructor(
private http: HttpClient
) { }
subscribe(ticker: string) {
if (this.tickers[ticker]) {
this.tickers[ticker]++;
} else {
this.tickers[ticker] = 1;
if (this.subscription) {
this.subscription.unsubscribe();
}
this.subscription = interval(60000).pipe(
switchMap(() => this.http.get<{ [ticker]: { name: string, price: number } }>(`api/crypto/${Object.keys(this.tickers).join(',')}`))
).subscribe(this.tickers$);
}
}
unsubscribe(ticker: string) {
if (this.tickers[ticker] > 1) {
this.tickers[ticker]--;
} else {
delete this.tickers[ticker];
if (Object.keys(this.tickers).length === 0) {
this.subscription.unsubscribe();
}
}
}
}
和组件中的
export class widgetComponent implements OnInit, OnDestroy {
@Input() ticker: string;
ticker$ = this.cryptoService.tickers$.pipe(
map(ticker => ticker && ticker[this.ticker])
);
constructor(
private cryptoService: CryptoService
) { }
ngOnInit() {
this.cryptoService.subscribe(this.ticker);
}
ngOnDestroy() {
this.cryptoService.unsubscribe(this.ticker);
}
}
并在模板中使用异步管道
<ng-content *ngIf="ticker$ | async as tickerVal">
{{ tickerVal.name }} current price is {{ tickerVal.price }}
</ng-content>