Angular 等待所有订阅
我有一个组件,当前设置如下:Angular 等待所有订阅,angular,promise,Angular,Promise,我有一个组件,当前设置如下: export class CompareComponent implements OnInit, OnDestroy { criteria: Criteria[] products: Product[] = []; private organisationId: string private criteriaSubscription: Subscription private routeSubscription: Subscription
export class CompareComponent implements OnInit, OnDestroy {
criteria: Criteria[]
products: Product[] = [];
private organisationId: string
private criteriaSubscription: Subscription
private routeSubscription: Subscription
private productSubscription: Subscription
constructor(
@Inject(PLATFORM_ID) private platformId: Object,
private route: ActivatedRoute,
private attributeMatchService: AttributeMatchService,
private criteriaService: CriteriaService,
private optionsService: OptionsService,
private productService: ProductService,
) { }
ngOnInit() {
this.organisationId = this.optionsService.get().organisation;
this.routeSubscription = this.route.paramMap.subscribe(paramMap => {
let category = paramMap.get('category');
let gtins = paramMap.get('gtins').split('.');
this.listCriteria(category);
this.listProducts(category, gtins);
});
}
ngOnDestroy() {
if (this.criteriaSubscription) this.criteriaSubscription.unsubscribe();
if (this.productSubscription) this.productSubscription.unsubscribe();
if (this.routeSubscription) this.routeSubscription.unsubscribe();
}
close() {
if (isPlatformServer(this.platformId)) return;
window.history.back();
}
private listCriteria(category: string): void {
this.criteriaSubscription = this.criteriaService.list(category, 'Attributes').subscribe(criteria => this.criteria = criteria);
}
private listProducts(category: string, gtins: string[]) {
gtins.forEach(gtin => {
this.productSubscription = this.productService.get(category, this.organisationId, parseInt(gtin)).subscribe(products => {
this.products.push(products[0]);
});
});
}
}
从listProducts
方法中可以看到,我得到了一个基于gtins的产品列表,这些产品已作为参数传递。
我想做的是等待所有订阅在listProducts
中完成,然后运行一些代码
我该怎么做?我相信您需要使用
forkJoin
它等待阵列中的所有可观测数据完成,然后发射
在每个可观察操作中执行轻触
private listProducts(category: string, gtins: string[]) {
const products$: Observable<any>[] = [];
gtins.forEach(gtin => {
products$.push(this.productService.get(category, 1, parseInt(gtin))
.pipe(tap(product => {
this.products.push(products[0]);
}));
});
forkJoin(products$).subscribe(() => {
console.log('All subscriptions done');
});
}
私有列表产品(类别:string,gtins:string[]){
const products$:可观察[]=[];
gtins.forEach(gtin=>{
products$.push(this.productService.get(category,1,parseInt(gtin))
.管道(水龙头)(产品=>{
这个.products.push(products[0]);
}));
});
forkJoin(产品$)。订阅(()=>{
log(“完成所有订阅”);
});
}
我相信您需要使用forkJoin
它等待阵列中的所有可观测数据完成,然后发射
在每个可观察操作中执行轻触
private listProducts(category: string, gtins: string[]) {
const products$: Observable<any>[] = [];
gtins.forEach(gtin => {
products$.push(this.productService.get(category, 1, parseInt(gtin))
.pipe(tap(product => {
this.products.push(products[0]);
}));
});
forkJoin(products$).subscribe(() => {
console.log('All subscriptions done');
});
}
私有列表产品(类别:string,gtins:string[]){
const products$:可观察[]=[];
gtins.forEach(gtin=>{
products$.push(this.productService.get(category,1,parseInt(gtin))
.管道(水龙头)(产品=>{
这个.products.push(products[0]);
}));
});
forkJoin(产品$)。订阅(()=>{
log(“完成所有订阅”);
});
}
如果要等待所有可观察到的结果,请使用forkJoin
操作符,然后将结果展平,将其推送到产品阵列中
我还建议使用takeUntil
操作符作为订阅的清理助手。请参见我的示例中如何使用它
forkJoin(
gtins.forEach(gtin => this.productService.get(category, this.organisationId, parseInt(gtin)))
).pipe(
takeUntil(this.destroyed$)
).subscribe(products => {
this.products.push(...products.flat())
});
在你的onDestroy
hook中
onDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
在组件中,将销毁的$
定义为
destrocted$:Subject=new Subject();
如果要等待所有观察值,请使用forkJoin
操作符,然后展平结果以将其推送到产品数组中
我还建议使用takeUntil
操作符作为订阅的清理助手。请参见我的示例中如何使用它
forkJoin(
gtins.forEach(gtin => this.productService.get(category, this.organisationId, parseInt(gtin)))
).pipe(
takeUntil(this.destroyed$)
).subscribe(products => {
this.products.push(...products.flat())
});
在你的onDestroy
hook中
onDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
在组件中,将销毁的$
定义为
destrocted$:Subject=新主题()
我想你是在寻找类似这样的东西来组合可观察对象并等待所有人,这是RxJs你可能还想查看我想你是在寻找类似这样的东西来组合可观察对象并等待所有人,这是RxJs你可能还想查看@ritaj击败我,但我将此作为参考对于一个链接式的答案。推入subscribe
而不是map
,不是更为惯用吗?(AFAIKmap
在函数式反应式编程中应该没有副作用)@meriton,非常正确,因为我们不变异数据,所以不需要映射!谢谢!)@meriton是的,它应该在点击
或订阅
@DanielB内部完成,不仅如此,您还可以将结果映射到此.products
数组的长度(因为推送返回数组长度),这将为以后的流链接丢失信息。@ritaj抢先告诉了我,但我将把它作为链接答案的参考。推入subscribe
而不是map
?(在函数式反应式编程中,AFAIKmap
应该是没有副作用的)@meriton,非常正确,因为我们不变异数据,所以不需要映射!谢谢!:)@meriton是的,应该在点击或订阅@DanielB内完成,不仅如此,您还可以将结果映射到this.products
数组的长度(因为推送返回数组长度),这将为以后的流链接丢失信息。