Как дождаться возврата нескольких вызовов asyn c http перед выполнением блока кода - PullRequest
0 голосов
/ 09 июля 2020

Мне известно о forkJoin , но моя проблема отличается от следующего кода

    getAllData() {
      let riskTable = this.getRiskTable();
      let risks = this.getAllRisks(); // should also return some observable
    
      forkJoin(riskTable, risks).subscribe(_ => {
        // all observables have been completed
      });
    }

Я выполняю много вычислений внутри каждого метода подписки, а HTTP-вызовы выполняются из разных методов и вычислений выполняются внутри самого метода .. Я не могу объединить все эти методы в один, потому что это приведет к дублированию кода, так как мне нужно вызывать эти методы отдельно в нескольких местах

например:

    ngOnInit(){
     this.getAllPartners()
     this.getAllUoms();
     this.getAllproductsByLocation();
     this.getAllLocations();
     this.getAllOperationTypes();

    }
    
    
      
      
getAllLocations(){
              this .queryResourceService.
              getAllLocationsForTransfersUsingGET(this.allLocParams).subscribe((data: 
               LocationDTO[]) => {
              this.locationDTOs = data;}) , 
              error=>console.log("error"),
              ()=> this.spinner.hide();
          }
getAllPartners(){
          this.spinner.show();
          this.queryResourceService.getAllPartnersUsingGET 
          (this.partnerParams).subscribe((data)={},
          error=>console.log("err"),
          ()=> this.spinner.hide())
        }
    
    
getAllproductsByLocation() {
                 this.spinner.show();
                 this.queryResourceService.
                 getAllProductsByLocationUsingGET(this.getAllProductsUsingGETParams)
                 .subscribe((data: StockDTO[]) => {
                                   this.stockDTOs = data;
                         },
                         error=>console.log("error"),
                         ()=>  this.spinner.hide())
      }

Теперь мне нужно выполнить блок кода после всех этих http вызовов внутри методов, возвращающих

 this.getAllPartners()
 this.getAllUoms();
 this.getAllproductsByLocation();
 this.getAllLocations();
 this.getAllOperationTypes();

т.е. после того, как все эти вызовы методов возвращаются, а также asyn c обратные вызовы внутри них завершены

, как я могу этого добиться?

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Вам не обязательно подписываться на каждую из наблюдаемых HTTP по отдельности. Вы можете использовать операторы Rx JS map (или tap), catchError, чтобы выполнять вычисления внутри каждого HTTP-запроса и возвращать наблюдаемый.

import { of, forkJoin } from 'rxjs';
import { map, tap, finalize, catchError } from 'rxjs/operators';

getAllLocations() {
  return this.queryResourceService.getAllLocationsForTransfersUsingGET(this.allLocParams).pipe(
    map((data: LocationDTO[]) => {
      this.locationDTOs = data;
      return data;          // <-- return `data`
    }),
    catchError((error) => {
      console.log("error");
      return of(error);     // <-- remember you must return an observable from `catchError` operator
    })
  );
}

getAllPartners() {
  return this.queryResourceService.getAllPartnersUsingGET(this.partnerParams).pipe(
    catchError((error) => {
      console.log("error");
      return of(error);     // <-- remember you must return an observable from `catchError` operator
    })
  );
}


getAllproductsByLocation() {
  return this.queryResourceService.getAllProductsByLocationUsingGET(this.getAllProductsUsingGETParams).pipe(
    catchError((error) => {
      console.log("error");
      return of(error)      // <-- remember you must return an observable from `catchError` operator
    })
  );
}

ngOnInit() {
  this.spinner.show();
  forkJoin(
    this.getAllPartners(),
    this.getAllUoms(),
    this.getAllproductsByLocation(),
    this.getAllLocations(),
    this.getAllOperationTypes()
  ).subscribe(
    null,
    err => { },
    () => this.spinner.hide();
  );
}

Теперь у вас есть единый источник подписки, и вы можете централизованно управлять флагом spinner. Таким образом, он не переключается между состояниями отображения и скрытия, когда выполняется несколько запросов. Если вы хотите sh что-то делать, когда каждый из наблюдаемых завершается индивидуально, тогда вы можете передать оператор finalize вместе с другими операторами.

0 голосов
/ 09 июля 2020

Здесь можно использовать ForkJoin. Вместо подписки в каждой функции get вы можете вернуть наблюдаемый и использовать forkJoin.

getAllLocations(){
    return this .queryResourceService.
        getAllLocationsForTransfersUsingGET(this.allLocParams);
}
getAllPartners(){
    this.spinner.show();
         this.queryResourceService.getAllPartnersUsingGET(this.partnerParams);
}
...

Затем в ngOnInit

ngOnInit(){
    forkJoin(
        this.getAllLocations()
        this.getAllPartners();
        ...
    )
    .subscribe(([locations, partners, ...]) => {
        this.handleLocationSubscription(locations);
        this.handlePartnerSubscription(locations);
        ...
        // Perform task after all async operatiojns resolved
    });
 
}

handleLocationSubscription(data: LocationDTO[]) {
    this.locationDTOs = data;
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...