Угловой шестипоточный оператор RxJs для цепочки 3 зависимых наблюдаемых - PullRequest
0 голосов
/ 06 июля 2018

У меня есть 3 зависимых ресурса API отдыха (скажем, наблюдаемые), например:

1-я наблюдаемая создает один элемент в виде массива пользователей, например:

getUsers(): Observable<User[]>
    [
      {
        "id": 1,
        "name": "Peter",
        "surname": "Smith"
      },
      {
        "id": 2,
        "name": "John",
        "surname": "Wayne"
      },
      ...
    ]

2-я наблюдаемая может использоваться для получения адресов, назначенных пользователю, поэтому входным параметром является идентификатор пользователя, и он возвращает один элемент в виде массива адресов:

getUserAddresses(user_id: string): Observable<Address[]>
    [
      {
        "id": 1,
        "city": "London",
        "street": "Wicombe 34"
      },
      {
        "id": 2,
        "city": "Paris",
        "street": "La fever 20"
      },
      ...
    ]

3-я наблюдаемая может использоваться для выбора компаний, назначенных пользователю, поэтому входным параметром является идентификатор пользователя, и возвращается один элемент в виде массива компаний:

getUserCompanies(user_id: string): Observable<Company[]>
    [
      {
        "id": 1,
        "name": "Fintch CO",
        "state": "France"
      },
      {
        "id": 2,
        "name": "C&C inc.",
        "state": "USA"
      },
      ...
    ]

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

    [
      {
        "id": 1,
        "name": "Peter",
        "surname": "Smith",
        "addreesses": 
               [
                 {
                   "id": "1",
                   "city": "London",
                   "street": "Wicombe 34"
                 },
                 {
                   "id": "2",
                   "city": "",
                   "street": "La fever 20"
                 }
               ],
        "companies": 
               [
                 {
                   "id": "1",
                   "name": "Fintch CO",
                   "state": "France"
                 },
                 {
                   "id": "2",
                   "name": "C&C inc.",
                   "state": "USA"
                 }
               ]
        }
      },
      {
        "id": 2,
        "name": "John",
        "surname": "Wayne",
        "addresses": [...],
        "companies": [...],
      },
      ...
    ]

Как должны выглядеть составные операторы для достижения этого в Angular 6 с RxJs 6? Большое спасибо за совет.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Чтобы связать наблюдаемые, вы можете использовать функцию flatMap. Тогда эта функция подобна обещаниям, то есть функция выполняется только после того, как наблюдаемое разрешено до значения.

Существует также наблюдаемая функция, называемая forkJoin, которая позволяет вам дождаться, пока несколько асинхронных запросов будут преобразованы в значение.

Пример:

getUsers().flatMap((users) => {
    // the users variable is the list of users
    var multipleObservables = [];
    users.forEach((u) => {
      multipleObservables.push(
         getUserAddresses(u.id).map((usersAddresses) => {
            u.addresses = usersAddresses;
            return u;
         });
      );
    });
    return forkJoin(multipleObservables);
}).flatMap((usersWithAddresses) => {
    // the usersWithAddresses variable is an array of users which also have their addresses
    var multipleObservables = [];
    usersWithAddresses.forEach((u) => {
       multipleObservables.push(
          getUserCompanies(u.id).map((usersCompanies) => {
             u.companies = usersCompanies;
             return u;
          });
       );
    });
    return forkJoin(multipleObservables);
});

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

0 голосов
/ 06 июля 2018

Как-то так может работать

getUsers()
.pipe(
  switchMap(users => from(users)),
  mergeMap(user => forkJoin(getAddresses(user.id), getCompanies(user.id))
                   .pipe(map(data => ({user, addresses: data[0], companies: data[1] })))
  tap(data => data.user.addresses = data.addresses),
  tap(data => data.user.addresses = data.companies),
  map(data => data.user),
  toArray()
  )
)

Применительно к другому варианту использования подобная цепочка объясняется более подробно здесь .

0 голосов
/ 06 июля 2018

Вот операторы для комбинации, они выдают результат в массиве ( ссылка ):

Я бы предложил прочитать их всем, чтобы понять, что вы предпочитаете, и найти лучший вариант для вашего сценария.

Надеюсь, это поможет!

...