Подождите, пока наблюдаемое завершится внутри массива. Карта - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть массив объектов, в котором один из ключей содержит идентификатор клиента.

const customerArray = [{ customerId: 123, ...}, { customerId: 456, ...}];

Я хочу перебрать этот массив и выполнить вызов API для получения дополнительной информации об этом клиенте от отдельная конечная точка.

const mapped = customerArray
  .map(customer => ({
    customerId: customer.customerId,
    rating: this.productService(customer.customerId)
               .pipe(map(rating => rating))}));

Я ожидаю, что тогда у меня будет массив, который включает в себя объект следующей формы:

{
  customerId: number,
  rating: number
}

Вместо этого я получаю:

{
  customerId: number,
  rating: Observable
}

Мой вызов productService возвращается на наблюдаемый и успешно используется в другом месте приложения. Мне нужно, чтобы мой map дождался завершения вызова с помощью ключа рейтинга, прежде чем сопоставить следующий элемент в массиве.

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Если я правильно понимаю, вы должны выполнить итерацию по массиву, сделать http-запрос к конечной точке для каждого элемента массива и заполнить каждый элемент массива данными, возвращаемыми конечной точкой. Так что, если это так, вы можете попробовать mergeMap вот так

const myObs = from(customerArray).pipe(
  mergeMap(customer => {
    return this.productService(customer.customerId).pipe(
      map(rating => ({customerId: customer.customerId, rating}))
    )
  })
)

Если вы подпишетесь на myObs, вы должны получить поток объектов в нужной форме, т.е.

{
  customerId: number,
  rating: number
}

mergeMap, ранее известный как flatMap, позволяет сгладить поток наблюдаемых. Другими словами, если вы перебираете массив для генерации массива Observables, что должно быть в вашем случае, mergeMap позволяет вам извлекать значения из сгенерированных Observables.

0 голосов
/ 18 февраля 2020

Я получил стековый блик , который показывает способ управления им, но для того, чтобы он всегда был доступен

import { Observable, of, from } from 'rxjs'; 
import { map, mergeMap, combineAll } from 'rxjs/operators';

const custArray = [{customerId: 1}, {customerId: 2}, {customerId: 3}];

function mapSomeStuff(id: number): Observable<number> {
  return of(id * id);
}

function doProductStuff(custArr: Array<{customerId: number}>): Observable<Array<{ customerId: number, rating: number}>> {
  return from(custArray)
    .pipe(
      map(async (cust) => ({
        customerId: cust.customerId,
        rating: await mapSomeStuff(cust.customerId).toPromise()
    })),
    combineAll()
  );
}

doProductStuff(custArray).subscribe(x => console.log(x))

Это разбивает массив и создает наблюдаемый для каждого значения в массиве запускает службу, преобразует наблюдаемое в обещание и получает его окончательное значение, а затем объединяет все наблюдаемые в одну наблюдаемую с массивом значений, являющимся окончательным результатом. Вы можете проверить вывод и увидеть [Object, Object, Object] и убедиться, что customerId и rating доступны для каждого Object.

...