[英]RxJS: untangle nested observables
我正在尋找一種比我現有的解決方案更具可讀性的解決方案。
我需要:1)從API檢索產品。 它們是objs數組。 2)根據類別等過濾這些產品。3)對產品進行分頁並返回這些產品的分頁版本。
ngOnInit() {
//This gets the products from the API
this.drinkSubscription = this.drinkService.getAllDrinks().subscribe(drinks => {
//Save products without pagination for other purposes
this.allDrinks = drinks;
//Get the parameter to filter products
this.paramSubscription = this.route.params.subscribe((params: Params) => {
//Filter the products and return a filtered array
const filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
//Sort products based on the selection
this.sorterSubscription = this.sorter.initialize(filteredDrinks).subscribe(sortedDrinks => {
//Create a pager that holds the paginated drinks in a property
this.pagerSubscription = this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5)
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
});
});
});
});
}
排序器和分頁是BehaviorSubjects,因此我可以注入next(),但我對它們並不滿意...您可以看到縮進程度很高,我想知道RxJS是否有辦法獲取以更易讀的方式得出相同的結果。
您應該能夠使用運算符將它們組合在一起。 我相信以下應該可行。
CombineLatest大致類似於Promise.all([p1,p2])
-僅當任何可觀察對象發射時,才會使用其他對象的先前值發射。
switchMap允許您獲取一個可觀察對象發出的值,並將其映射到另一個可觀察對象。
https://www.learnrxjs.io/operators/combination/combinelatest.html https://www.learnrxjs.io/operators/transformation/switchmap.html
例如:
let drinkObservable = this.drinkService.getAllDrinks()
let paramsObervable = this.route.params
let sub = combineLatest(drinkObservable, paramsObervable)
.pipe(switchMap(([drinks, params]) => {
this.allDrinks = drinks
let filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
return this.sorter.initialize(filteredDrinks)
}))
.pipe(switchMap(sortedDrinks => {
return this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5)
}))
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
})
一般subscribe
內subscribe
是一個“代碼氣味”,這隱藏了“扁平化”的策略與平坦化等運營商中的一個來實現的需要mergeMap
(又名flatMap
), switchMap
, exaustMap
, concatMap
(這是mergeMap
並發設置為1)。
那么在您的特定情況下,代碼可能會變成類似
ngOnInit() {
//This gets the products from the API
this.drinkSubscription = this.drinkService.getAllDrinks().switchMap(drinks => {
this.allDrinks = drinks;
return this.route.params)
})
.switchMap((params: Params) => {
const filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
return this.sorter.initialize(filteredDrinks)
})
.switchMap(sortedDrinks => this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5))
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
});
});
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.