我怎样才能重构这个RXJS / Angular代码?

时间:2018-06-01 23:33:50

标签: javascript angular rxjs

如何重构这些嵌套数组,以便在完成所有订阅后我可以调用某些内容?我确信它与管道,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 :(得分:2)

用lodash:

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 
    }
)

答案 1 :(得分:0)

您无法收听订阅,但是,您可以为每个作业返回一个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;
  });
});

<强> P.S。我想到的一些替代语法是:

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的粉丝,所以我只是想提出一个香草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
  });