Как я могу реорганизовать этот код RXJS / Angular? - PullRequest
0 голосов
/ 02 июня 2018

Как я могу провести рефакторинг этих вложенных массивов, чтобы я мог что-то вызвать после завершения всех подписок?Я уверен, что это связано с сочетанием каналов, mergeMaps, concatMaps и т. Д.

this.teams = [
{
    Assignments: [{Id: 0, Name: 'assignment', Notes: 'notes'}]
},
{
    Assignments: [{Id: 0, Name: 'assignment', Notes: 'notes'}]
}]
    this.teams.map((team:any) => {
        team.Assignments.map((a: Assignment) => {
          return this.videoService.getById(a.VideoId).subscribe(
            res => {
              let e = new Event();
              e.Id = a.Id;
              e.title = a.Name;
              e.location = '';
              e.message = a.Notes;
              e.startDate = a.StartDate;
              e.endDate = a.EndDate;
              e.video = res;
              e.team = team.Name;
              this.eventList.push(e);
            },
            err => {

          });
        })
      })

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

С Лодаш:

Observable.from(
    lodash.flatten(
        this.teams.map(team => team.Assignments)
        )
)
.flatMap(a => this.videoService.getById(a.VideoId))
. subscribe(
    res => {
        //handle individual responses
    },
    err => {},
    () => {
        //handle after all complete 
    }
)
0 голосов
/ 02 июня 2018

Вы не можете прослушивать подписки, однако вы можете вернуть наблюдаемое для каждого назначения и выполнить forkJoin из них, что-то вроде:

this.teams.map((team:any) => {
  forkJoin(...team.Assignments.map((a: Assignment) => {
    return this.videoService.getById(a.VideoId).map(
      res => {
        const e = new Event();
        e.Id = a.Id;
        e.title = a.Name;
        e.location = '';
        e.message = a.Notes;
        e.startDate = a.StartDate;
        e.endDate = a.EndDate;
        e.video = res;
        e.team = team.Name;
        this.eventList.push(e);
      });
  })).subscribe(data => {
    // Do something;
  })
})

Теперь я бы немного поменялкод для того, чтобы сделать его более читабельным, что-то вроде:

function mapToEvent(team, assignment, response) {
  const e = new Event();
  e.Id = assignment.Id;
  e.title = assignment.Name;
  e.location = '';
  e.message = assignment.Notes;
  e.startDate = assignment.StartDate;
  e.endDate = assignment.EndDate;
  e.video = response;
  e.team = team.Name;
  return e;
}

this.teams.map(team => {
  forkJoin(
    ...team.Assignments.map(a =>
      this.videoService
        .getById(a.VideoId)
        .map(res => mapToEvent(team, a, res))
        .do(event => this.events.push(event))
    )
  ).subscribe(data => {
    // Do something;
  });
});

ps. Некоторый альтернативный синтаксис, над которым я подумал:

function mapToEvent(team, assignment, response) {
  const obj = {
    Id: assignment.Id,
    title: assignment.Name,
    location: '',
    message: assignment.Notes,
    startDate: assignment.StartDate,
    endDate: assignment.EndDate,
    video: response,
    team: team.Name
  };

  return Object.assign(new Event(), obj);
}

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

Основано на другом ответе

Я не большой поклонник lodash, поэтомуЯ просто хотел представить альтернативу vanilla js:

Observable.from(
  this.teams
    .map(team => team.Assignments)
    .reduce((acc, a) => [...acc, ...a], [])
)
  .flatMap(a => this.videoService.getById(a.VideoId))
  .catch(err => {
    // Do Something
  })
  .finally(() => {
    // Do something
  })
  .subscribe(res => {
    // Handle Single
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...