【问题标题】:How to wait for subscribe inside subscribe?如何在订阅中等待订阅?
【发布时间】:2021-06-08 17:12:16
【问题描述】:

我需要订购一系列产品。但是 getProduct() 的工作时间比我需要的晚,并且所有产品都未定义。我发现嵌套订阅的方式不好,那么使用mergeMap/switchMap的正确方法是什么

getOrder(id: string) {
  this.orderService
    .getOrder(id)
    .subscribe(order => {
      order.map(item => {
        data.push(item.payload.doc.data());
        return data;
      });
      this.order = data[0].products.map(x => this.getProduct(x))
    });
}

getProduct(id: string) {
  return this.productService
    .getProduct(id)
    .subscribe(product => product);
}

 getOrderById(id: string): Observable < any > {
  return this.afs
    .collection('orders', ref => ref.where('uid', '==', id))
    .snapshotChanges();
}
 getProductById(id: string): Observable < any > {
  return this.afs
    .collection('products', ref => ref.where('uid', '==', id))
    .valueChanges();
}

【问题讨论】:

标签: angular rxjs subscription


【解决方案1】:

我看到您在这里有 2 个彼此独立的可观察对象。

  1. getOrderById() 2) getProductById()

您可以将这两个 observable 组合起来,只订阅一次,也可以取消订阅。像这样的:


const orderByIdObservable = this.getOrderById();
const productByIdObservable = this.getProductById();

destroy$: Subject<any> = new Subject(); // This is used to destroy the subscription later

************************************************************
 *********** Using 'combineLatest' RXJS operator **********
************************************************************
// Combine the observables and destroy once done, in 1 shot.

combineLatest(orderByIdObservable,productByIdObservable)
  .pipe(
      takeUntil(this.destroy$),
      take(1)
   )
  .subscribe(
     ([orderByIdObservableData, productByIdObservableData]) => {
        if (orderByIdObservableData && productByIdObservableData) {
          // do your logic here
        }  
     }
  );

ngOnDestroy() {
   this.destroy$.next();
   this.destroy$.complete();
}



A) combineLatest - will combine all the observables and subscribe only once
B) takeUntil - this will keep subscribing until the destroy$ is completed/closed
C) take(1) - this will always take only the first value. You may or may not want to keep this
D) destroy$ - Use the Subject variable to destroy the service one the component is destroyed


************************************************************
 *********** Using 'mergeMap' RXJS operator **********
************************************************************

orderByIdObservable
  .pipe(
    mergeMap(productIdObsData => productByIdObservable.pipe(tap(data => !!data)),
    takeUntil(this.destroy$),
    take(1)
  )
  .subscribe(data => {
     console.log('Both the data merged into one', data);
     // here both the observables data are merged into one data variable
  })



A) mergeMap - if the data of the first observable is successfully subscribed, then only this mergeMap works otherwise the data after merging and subscribing is either null, undefined or some random object.
B) takeUntil - this will keep subscribing until the destroy$ is completed/closed
C) take(1) - this will always take only the first value. You may or may not want to keep this
D) destroy$ - Use the Subject variable to destroy the service one the component is destroyed

combineLatest 相对于 mergeMap 的优势是您将只有一个订阅和一个取消订阅,而在 mergeMap 中您将有 2 个。

【讨论】:

    猜你喜欢
    • 2021-05-06
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 2017-11-11
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多