如何同时运行Observable,但在Angular中组合响应



在我的Angular App中,我调用了两个API,一个返回X项的通用数据,另一个API返回它的图像。

我会同时运行两个调用,显示通用数据,因为API是响应更快的一个,然后我会用从另一个API获得的图像更改从info-API获得的对象。

目前,我的代码是两个API的forkJoin,但在这一点上,我将只在两个API都完成时显示这些项。

这是我的代码:

ngOnInit(): void {
forkJoin([this.negoziService.negozi(), this.negoziService.images()]).subscribe(data => {
this.arrNegozi = data[0];
data[1].map((i) => {
const image = this.arrNegozi.find((d) => d.id === i.id);
image !== undefined
? image.logo = 'data:image/jpg;base64,' + i.img
: image.logo = null;
});
}, error => {
this.errore = error;
})
}

编辑:

正如注释中所建议的,我刚刚将代码更改为combineLatest,但代码的行为仍然相同。

combineLatest([this.negoziService.negozi(), this.negoziService.images()]).subscribe(([nagozi, images]) => {
this.arrNegozi = nagozi;
images.map((img) => {
const negozio = this.arrNegozi.find((d) => d.id === img.id);
negozio !== undefined ? negozio.logo = 'data:image/jpg;base64,' + img.img : negozio.logo = 'assets/images/no_image.svg';
})
},
error => {
this.errore = error;
}
)

用法是在加载图像时显示骨架,但尽快显示从第一个API获得的文本数据

我认为您可以发出独立的请求,并控制响应以及如何合并它们。通过这种方式,您可以控制arrNegozi并显示它们,同时控制arrImages,并显示骨架,直到加载arrNegozi。首先尝试将这两种信息作为属性进行管理,

arrNegozi: any[];   // I dont know type of your attribute
arrImages: any[] = [];

在ngOnInit中,您在将negozi与图像合并时进行分离请求和管理

this.negoziService.negozi().subscribe((negozi) => {
this.arrNegozi = negozi;
// if the request for images response first, and arrImages are already loaded and has data, then merge negozi with images
if(this.arrImages.length > 0){
this.mergeNegoziWithImages();
}
},
error => {
this.errore = error;
}
)
this.negoziService.images().subscribe((images) => {
// save data on your attribute 
this.arrImages = images;
// If the request for negozi response first and  arrNegozi are already loaded and has data, then merge negozi with images
// 
if(this.arrNegozi.length > 0){
this.mergeNegoziWithImages();
}
},
error => {
this.errore = error;
}
)

实现方法,以合并您的arrNegozi和您的arrImages时可用。

mergeNegoziWithImages(){
// I wrote this guessing about your algorithm, feel free to make your own implementation of the union
this.arrImages.foreach((i)=> {
const image = this.arrNegozi.find((d) => d.id === i.id);
image !== undefined
? image.logo = 'data:image/jpg;base64,' + i.img
: image.logo = null;
})
// Maybe you have to slice arrNegozi to change reference in memory to that array and generate ngOnChanges to be execute.
this.arrNegozi = this.arrNegozi.slice();
}

最新更新