以下代码给出了运行时错误,因为top5Ids
未定义。当我正确订阅可观察对象并从订户top5Ids
方法内部设置next
变量时,我真的不太理解为什么未定义此变量。
cryptoService类只是返回http.get()函数的结果,这是可以观察到的。
export class HomeComponent implements OnInit {
cryptoDetails: CryptoDetail[];
top5Ids: string[];
constructor(private cryptoService: CryptoService) { }
ngOnInit() {
this.cryptoDetails = new Array();
this.getTop5Crypto();
this.getCryptoData(this.top5Ids);
const source = interval(5000).subscribe(val => this.getCryptoData(this.top5Ids))
}
getCryptoData(ids: string[]){
this.cryptoDetails = [];
console.log("get crypto")
for(let id of ids){
this.cryptoService.getCryptoInfo(id).subscribe(res => {
let data = res.data;
let cryptoDetail = new CryptoDetail(data.id, data.rateUsd, data.symbol);
this.cryptoDetails.push(cryptoDetail);
})
}
this.cryptoDetails.sort();
}
getTop5Crypto() : void {
let top5CryptoIds : string[] = [];
this.cryptoService.getCryptoMarkets().pipe(take(1)).subscribe(res => {
let data = res.data;
for(let i = 0; i < 6; i++) {
top5CryptoIds.push(data[i].baseId)
}
this.top5Ids = top5CryptoIds;
});
}
}
答案 0 :(得分:1)
在Angular中,最好完全包含函数式反应式编程。
您可以按以下方式重写代码:
export class HomeComponent implements OnInit {
cryptoDetails: CryptoDetail[];
top5Ids$: Observable<string[]>;
constructor(private cryptoService: CryptoService) { }
ngOnInit() {
this.top5Ids$ = this.getTop5Crypto();
timer(0, 5000).pipe(
switchMap(() => this.top5Ids$),
switchMap((top5Ids) => this.getCryptoData(top5Ids))
).subscribe((cryptoDetails) => {
this.cryptoDetails = cryptoDetails;
})
}
getCryptoData(ids: string[]): Observable<CryptoDetail[]> {
return forkJoin(ids.map(id => this.cryptoService.getCryptoInfo(id)))
.pipe(
map(responses => responses.map(r => new CryptoDetail(r.data.id, r.data.rateUsd, r.data.symbol)).sort())
);
}
getTop5Crypto() : Observable<string[]> {
return this.cryptoService.getCryptoMarkets().pipe(
take(1),
map((res: any) => res.data.filter((d, i) => i < 5).map(d => d.baseId)),
);
}
}
功能反应式编程的思想是,我们编写对DOM事件和Http响应之类的东西做出反应的代码,然后通过一系列(理想情况下是纯函数)将转换应用于与这些事件相关的数据。
我们尝试避免在管道结束时创建手动订阅(有时甚至在使用Angular异步管道时也是如此)。这样,我们得到了一个很好的可预测的异步事件管道,并避免了诸如竞争条件之类的问题。
警告是要执行这些操作,您必须对RxJS有深刻的了解。