Угловые множественные наблюдаемые http-вызовы после одного - PullRequest
0 голосов
/ 23 октября 2019

У меня есть несколько служб, которые получают http-ответ от сервера.

export abstract class ServiceBase<T>{
    getAll(){console.log(`${this.url}/${this.endpoint}`)
        return this.http.get<any[]>(`${this.url}/${this.endpoint}`);
    }

    get(id: any){
        return this.http.get<any>(`${this.url}/${this.endpoint}/${id}`);
    }
}

@Injectable()
export class Service1 extends ServiceBase<any> {
    constructor(http: HttpClient) {
        super(http, "http://localhost:60211", "s1");
    }
}

@Injectable()
export class Service2 extends ServiceBase<any> {
    constructor(http: HttpClient) {
        super(http, "http://localhost:60211", "s2");
    }
}


@Injectable()
export class Service3 extends ServiceBase<any> {
    constructor(http: HttpClient) {
        super(http, "http://localhost:60211", "s3");
    }
}

И я использую это в приложении.

export class AppComponent {
     s1: {};
     s2: any[];
     s2: any[];
     constructor(service1:Service1, service2:service2, service3:service3){
        service1.get("123").subscribe({       
          next: response => {
            this.s1=response;
            service2.getAll().subscribe({
                    next: response => {
                        this.s2 = response;
                    }
            });
            service3.getAll().subscribe({
                    next: response => {
                        this.s3 = response;
                    }
            })
          }
         })
     }
}

Но ответы s3 и s2 не приходят с сервера,Это это использование ложно? Но когда я запускаю сервис из почтальона, сервис работает.

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Для достижения желаемого результата вам нужны операторы switchMap и combineLatest.

Это будет выглядеть примерно так:

service1.get("123").pipe(
    switchMap(() => combineLatest(service2.getAll(), service3.getAll())),
).subscribe(([service2Data, servoce3Data]) => {
    // do your stuff
});
0 голосов
/ 25 октября 2019

Вот пример forkJoin. Чтобы убедиться, что синтаксис правильный и работает, это из моего кода (а не из кода OP).

  // Suppliers for the selected product
  // Only gets the suppliers it needs
  // switchMap here instead of mergeMap so quickly clicking on the items 
  // cancels prior requests.
  selectedProductSuppliers$ = this.selectedProduct$
    .pipe(
      filter(selectedProduct => Boolean(selectedProduct)),
      switchMap(selectedProduct =>
        forkJoin(selectedProduct.supplierIds.map(supplierId => this.http.get<Supplier>(`${this.suppliersUrl}/${supplierId}`)))
      ),
      tap(suppliers => console.log('product suppliers', JSON.stringify(suppliers)))
    );

Этот код получает уведомление каждый раз, когда выбирается новый продукт (this.selectedProduct)

Затем он передает выборку с помощью набора операций:

  • Отфильтровывает пустой выбранный продукт (например, когда страница отображается в первый раз, а пользователь еще невыбрал продукт)

  • Он использует switchMap, поэтому, если пользователь выбирает продукт 1, продукт не 2, продукт 3, в быстрой последовательности, он будет излучать только продукт 3.

  • Он использует forkJoin, чтобы взять каждый идентификатор поставщика, определенный для выбранного продукта, и использовать его для получения подробных данных о поставщике, а затем объединяет всех поставщиков в один массив и создает этот массив.

selectedProductSuppliers является тогда Observable<Supplier[]> и выдает список поставщиков для выбранного продукта.

Полный код можно найти здесь: https://github.com/DeborahK/Angular-RxJS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...