Angular Rxjs组合流

Angular Rxjs组合流,angular,rxjs,behaviorsubject,Angular,Rxjs,Behaviorsubject,好的,基本上我想要实现的是一个依赖于另一个可观察对象的可观察对象,比如一个联合查询。 为了更详细地说明,我有两个表,一个是活动表,另一个是这些活动的最终日期表,所以我要做的是首先获取这些活动,然后搜索这些活动的最终日期,最好能够组合这两个流,以返回一个包含单个新对象中的活动和最终日期的数组 我尝试了不同的实现,但没有任何运气 下面是我如何实现我的service.ts(两个表的服务都是相同的): (这不可编译) 平面图: this.actividadService.getActividades()

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

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

下面是我如何实现我的service.ts(两个表的服务都是相同的):

(这不可编译)

平面图:

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();
这确实可以编译,但不起作用

最后一个是最接近我的,但我知道这是一个糟糕的可观测实现:

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();
this.actividadService.getActividades().flatMap((actividades:any[])=>{
如果(actividades.length>0){
返回可观察的forkJoin(
actividades.map((actividad:any)=>{
返回此.actividadFechasFinalService.getactividadbyidear(actividad.ID,actividad.Anio)
.map((res:any)=>{
让我们行动起来;
控制台日志(res);
log('j='+this.j);
这个.j++;
如果(分辨率长度>0){
res.map((对象)=>{
console.log(this.i);
这个.i++;
console.log(对象);
console.log('object');
//console.log(res[0].FechaFinal);
//让对象:any=res;
actividadPlaneacion=新ActividadPlaneacionMasFechasFinales(actividad.ID,actividad.description,actividad.Nombre,actividad.FechaInicio,actividad.Responsible,
actividad.Practica,actividad.departmento,actividad.Evidencia,actividad.Producto,object.actividad,object.FechaFinal,object.Completado,actividad.Anio);
让exists=this.arreglo.find(fecha=>fecha.FechaFinal==actividPlaneAcion.FechaFinal);
console.log(存在);
如果(存在==未定义)
此.arreglo.push(活动平面);
this.arreglo=this.arreglo.sort(函数(a,b){
如果(a.粪便b.粪便)
返回1;
返回0;
});
});
}否则{
让existsActividad=this.arreglo.find(fecha=>fecha.FechaFinal==actividad.FechaFinal);
console.log(existsActividad);
if(existsActividad==未定义){
actividadPlaneacion=新ActividadPlaneacionMasFechasFinales(actividad.ID,actividad.description,actividad.Nombre,actividad.FechaInicio,actividad.Responsible,
actividad.Practica,actividad.departmento,actividad.emplicia,actividad.Producto,null,null,null,actividad.Anio);
}否则{
常量索引:number=this.arreglo.indexOf(existsActividad);
如果(索引!=-1){
这个.arreglo.拼接(索引,1);
}
}//卡皮图洛
让exists=this.arreglo.find(fecha=>fecha.FechaFinal==actividPlaneAcion.FechaFinal);
console.log(存在);
如果(存在==未定义)
此.arreglo.push(活动平面);
}
返回活动计划;
});
})
);
}
console.log('FINALLL');
如果(actividades.length==0)
这个.getActividades();
返回活动;
}).订阅(
actividades=>this.arregoloActividadesFlatMap=actividades
);
this.actividadService.loadActividades();

我在使用这种方法时遇到的另一个问题是,如果嵌套的obervable没有返回任何内容,那么它就不起作用,因此我不得不做一个临时解决方案,但我想知道如果嵌套的obervable没有返回任何内容,flatMap或mergeMap是否起作用。为了将一个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));

为了将一个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));

哇,谢谢你,伙计,这是一个非常简洁的回答。我试着实现你的代码,然后我就去了
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));