簡體   English   中英

RxJS:解開嵌套的可觀察對象

[英]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;
  })

一般subscribesubscribe是一個“代碼氣味”,這隱藏了“扁平化”的策略與平坦化等運營商中的一個來實現的需要mergeMap (又名flatMap ), switchMapexaustMapconcatMap (這是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM