Как я могу изменить порядок в подписке?

Как изменить порядок выполнения? У меня есть массив this.friend, мне нужно работать с этим массивом, но требуется заполнить данными

this.listUserService.getUsers().subscribe(
    async (data: any) => {
           this.listUsers = data;
           await data.forEach((current: any) => {
                 if (current.name === userSession) {
                      this.user = current;
                      this.friendsService.getFriends(this.user.id).subscribe(response => {
                                console.info('last', response);//this runs second
                                this.friends = response;
                            });
                        }
                    });
                    console.info('friends', this.friends); //friend is clear, 
this runs first
                    this.listUsers = this.listUsers.filter(user => !this.friends.some(relationship => relationship[0].friend.id !== user.id));
                }
            );

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

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
457
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Нет необходимости смешивать обещания с наблюдаемыми. Кроме того, не рекомендуется вкладывать subscribe() методы друг в друга. Я бы порекомендовал вам выполнить вышеуказанную операцию с операторами RxJS.

Во-первых, мы используем карта слияния для отображения наблюдаемых значений из метода getUsers() из службы во внутреннюю наблюдаемую.

Затем мы используем forkJoin, чтобы дождаться завершения цикла Array.forEach(), прежде чем вернуть все наблюдаемые. Поскольку вы, кажется, знакомы с использованием промисов в JavaScript, на самом деле это похоже на Promise.all.

И последнее, но не менее важное: мы обрабатываем фильтрацию listUsers в блоке subscribe(). Это обеспечит правильную обработку вашего асинхронного кода.

this.listUserService.getUsers().pipe(
  mergeMap(data => {
    this.listUsers = data;
    const observablesList = [];
    data.forEach((current: any) => {
      if (current.name === userSession) {
        observablesList.push(this.friendsService.getFriends(current.id));
      }
    });
    return forkJoin(observablesList);
  })
).subscribe(response => {
  // console.info(response) will give you the returned values from the looped getFriends()
  // handle the rest here

});

Вместо этого вы можете попробовать использовать операторы RxJS, такие как переключательКарта, карта и кран, для управления потоком наблюдаемого, включая выполнение побочных эффектов, таких как установка свойств класса.

Этот ответ предполагает, что существует только один текущий пользователь, полученный в результате if (current.name === userSession) { внутри forEach(), и, следовательно, this.friendsService.getFriends(user.id) выполняется только один раз.

import { map, switchMap, tap } from 'rxjs/operators'; // need to import operators

// ...

this.listUserService.getUsers().pipe(
  tap(users => this.listUsers = users), // side effect to set this.listUsers
  map(users => users.find(user => user.name === userSession)), // find current user
  switchMap(user => this.friendsService.getFriends(user.id)), // get friends of current user
  tap(friends => this.friends = friends), // side effect to set this.friends
  map(friends => this.listUsers.filter(user => this.friends.some(relationship => relationship[0].friend.id !== user.id)))
).subscribe(listUsers => {
  this.listUsers = listUsers;
});

Вам обязательно следует просмотреть документацию RxJS для получения дополнительной информации и примеров различных операторов. Также вам определенно потребуется улучшить обработку ошибок в случае таких ситуаций, как текущий пользователь не найден или какой-либо из вызовов службы/API не работает.

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

Это потому, что вы неправильно используете потоки RxJS. Сначала вы настраиваете свой поток, чтобы любой другой console.info запускался первым. Поток Rx сам по себе асинхронный, поэтому вам не нужно async await. Другой console.info будет работать, когда поток действительно вызывается и получает данные.

Способ RxJS заключался бы в том, чтобы .pipe() ваш filter() внутри потока Rx.

Это не столько проблема Angular, сколько RxJS. Вот пример того, как это может выглядеть:

   this.listUserService
  .getUsers()
  .pipe(
    tap(listUserData => {
      this.listUsers = listUserData;
    }),
    switchMap(data => {
      return this.friendsService.getFriends(data.id).pipe(
        tap(friends => {
          this.friends = friends;
        })
      );
    })
  )
  .subscribe();

switchMap переключается на другую наблюдаемую под водой, поэтому вам не нужны две подписки. Это считается хорошей практикой!

Я настоятельно рекомендую потратить некоторое время на изучение RxJS, это сделает ваш опыт работы с Angular намного более приятным и продуктивным!

Я могу помочь тебе с этим, если хочешь!

Другие вопросы по теме