【问题标题】:Rxjs combining streamsRxjs 组合流
【发布时间】:2017-11-24 19:48:08
【问题描述】:

好的,基本上我想要实现的是一个依赖于另一个可观察对象的可观察对象,例如联合查询。 为了详细说明,我有两张表,一张是活动,另一张是这些活动的最终日期,所以我要做的是首先获取活动,然后搜索这些活动的最终日期,最好是能够将两个流结合起来,在一个新对象中返回一个包含活动和最终日期的数组。

我尝试了不同的实现,但没有任何运气。

以下是我实现 service.ts 的方式(表的两个服务相同):

private actividadesSubject = new BehaviorSubject([]);
private actividades: ActividadPlaneacion[];
// <------------------------ GET ------------------------>
getActividades(): Observable<ActividadPlaneacion[]>{
   return this.actividadesSubject.asObservable();
}
loadActividades(){
  var sub = this.http.get(this.url+'select/actividadPlaneacion')
      .map(this.extractData)
      .catch(this.handleError);
  sub.subscribe(
    data => this.actividades = data,
    err => console.log(err),
    () => this.refresh()
  );
}
private refresh() {
  this.actividadesSubject.next(this.actividades);
}

我尝试过的各种方法(在 component.ts 上): 合并地图

this.actividadService.getActividades().mergeMap( actividad => 
  this.actividadFechasFinalService.getActividadByIDYear(actividad.ID, actividad.Anio).subscribe( actividades => this.arregloActividadesFlatMap = actividades ));

(这不会编译)

平面图:

this.actividadService.getActividades().flatMap( actividad => {
  this.actividadFechasFinalService.getActividadByIDYear(actividad[0].ID, actividad[0].Anio).subscribe( actividades => this.arregloActividadesFechasFinales = actividades );
  return Observable.of(actividad)});
this.actividadService.loadActividades();

这确实编译但不起作用

最后一个是我最接近它的工作,但我知道这是一个糟糕的 observables 实现:

this.actividadService.getActividades().flatMap((actividades: any[]) => {
  if(actividades.length > 0){
    return Observable.forkJoin(
      actividades.map((actividad: any) => {
        return this.actividadFechasFinalService.getActividadByIDYear(actividad.ID, actividad.Anio)
          .map((res: any) => {
            let actividadPlaneacion;
            console.log(res);
            console.log('j = '+this.j);
            this.j++;
            if(res.length > 0){
              res.map( (object) => {
                console.log(this.i);
                this.i++;
                console.log(object);
                console.log('object');
                //console.log(res[0].FechaFinal);
                //let object: any = res;
                actividadPlaneacion = new ActividadPlaneacionMasFechasFinales(actividad.ID, actividad.Descripcion, actividad.Nombre, actividad.FechaInicio, actividad.Responsable,
                  actividad.Practica, actividad.Departamento, actividad.Evidencia, actividad.Producto, object.Actividad, object.FechaFinal, object.Completado, actividad.Anio);
                let exists = this.arreglo.find(fecha => fecha.FechaFinal == actividadPlaneacion.FechaFinal);
                console.log(exists);
                if(exists == undefined)
                  this.arreglo.push(actividadPlaneacion);
                this.arreglo = this.arreglo.sort(function(a, b){
                  if ( a.FechaFinal < b.FechaFinal )
                      return -1;
                  if ( a.FechaFinal > b.FechaFinal )
                      return 1;
                  return 0;
                });
              });
            } else{
              let existsActividad = this.arreglo.find(fecha => fecha.FechaFinal == actividad.FechaFinal);
              console.log(existsActividad);
              if(existsActividad == undefined){
                actividadPlaneacion = new ActividadPlaneacionMasFechasFinales(actividad.ID, actividad.Descripcion, actividad.Nombre, actividad.FechaInicio, actividad.Responsable,
                  actividad.Practica, actividad.Departamento, actividad.Evidencia, actividad.Producto, null, null, null, actividad.Anio);
              } else {
                const index: number = this.arreglo.indexOf(existsActividad);
                if (index !== -1) {
                    this.arreglo.splice(index, 1);
                }
              } //capitulo
              let exists = this.arreglo.find(fecha => fecha.FechaFinal == actividadPlaneacion.FechaFinal);
              console.log(exists);
              if(exists == undefined)
                this.arreglo.push(actividadPlaneacion);
            }
            return actividadPlaneacion;
          });
      })
    );
  }
  console.log('FINALLL');
  if(actividades.length == 0)
    this.getActividades();
  return actividades;
}).subscribe(
  actividades => this.arregloActividadesFlatMap = actividades
);
this.actividadService.loadActividades();

我在使用这种方法时遇到的另一个问题是,如果嵌套的 obervable 没有返回任何内容,它就不起作用,所以我不得不做一个临时解决方案,但我想知道如果嵌套的 observables 返回,flatMap 或 mergeMap 是否不起作用什么都没有

【问题讨论】:

    标签: angular rxjs behaviorsubject


    【解决方案1】:

    为了将一个 http 调用的结果提供给第二个调用,您可以使用 switchMap、mergeMap 或 concatMap。

    forkJoin 更适合您有多个调用而不是独立运行并且您只想在所有调用返回后合并所有调用的结果。

    选择的选项取决于您希望如何处理多个并发调用,例如。如果用户多次单击加载按钮并将多个请求排队,会发生什么?总结:

    • switchMap - 将丢弃所有未完成的请求并仅返回 上次触发的请求的结果
    • mergeMap - 将按顺序返回所有并发请求 他们从服务器返回(可能与 他们被要求的
    • concatMap - 将按顺序返回所有结果 请求

    使用 switchMap 的一个简单示例是:

    this.http.get('https://jsonplaceholder.typicode.com/posts')
    .switchMap((result) => {
    
       // add your logic here to get data from first request to
       // feed to second request
       const firstId = result.response[0].id
    
       if (firstId) {
    
           return this.http.get('https://jsonplaceholder.typicode.com/comments/' + firstId);
    
       } else {
    
           // if you don't have what you need return your own observable
           return Observable.of('No results');
    
       }
    
    })
    .subscribe(result => console.log(result));
    

    【讨论】:

    • 哇,谢谢,这是一个伟大而简洁的答案。我尝试实现您的代码,但出现此错误:无法从用法中推断类型参数“R”的类型参数。考虑明确指定类型参数。候选类型参数“ActividadPlaneacionFechaFinal[]”不是有效的类型参数,因为它不是候选“字符串”的超类型。
    • 好的,我根据你的代码让它工作了,现在的问题是内部流只对结果数组中的第一个对象执行,我需要从结果数组中获取所有日期,尝试使用 for 但它不起作用
    • 代码:this.actividadService.getActividades() .switchMap((result) => { const actividadUno = result[0]; if (actividadUno) { for(let actividad of result){ 返回这个。 actividadFechasFinalService.getActividadByIDYear(actividad.ID, actividad.Anio).catch(this.handleError); } } else { return Observable.of('No results'); } }, (actividades, actividadesFechas)=>[actividades, actividadesFechas] ) .subscribe(actividades => this.arregloActividadesFlatMap = actividades);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2016-07-08
    • 2017-06-15
    • 2020-09-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多