RxJs:您能将运算符作为参数传播到管道运算符中吗

RxJs:您能将运算符作为参数传播到管道运算符中吗,rxjs,rxjs-pipeable-operators,rxjs-observables,Rxjs,Rxjs Pipeable Operators,Rxjs Observables,我有两个可观察的流,它们执行非常独立的映射逻辑,但最终以以下3个运算符结束: this.selection .pipe( ..Custom mapping operators tap(_ => this.devicesLoading = true), switchMap(d => this.mapService.findLocationForDevices(d)), map(loc => marker([loc.lat

我有两个可观察的流,它们执行非常独立的映射逻辑,但最终以以下3个运算符结束:

  this.selection
    .pipe(
      ..Custom mapping operators
      tap(_ => this.devicesLoading = true),
      switchMap(d => this.mapService.findLocationForDevices(d)),
      map(loc => marker([loc.latitude, loc.longitude])
    )
    .subscribe(markers => this.plotMarkers(markers));
我想将最后一个
点击、开关映射、映射
操作符移动到一个公共函数,这样我就可以在两个可观察的流中应用它们

我想做:

  private resolveLocationsAndConvertToMarkers = (devices: String[]) => [
    tap(_ => this.devicesLoading = true),
    switchMap((devices: string[]) => this.mapService.findLocationForDevices(devices)),
    map(loc => marker([loc.latitude, loc.longitude])
  ];
但我不确定如何将这些运算符扩展到管道参数中,例如:#


此错误提示
不存在期望3个或5个参数的重载。

您可以尝试使用本机
.apply()

或者将操作符列表包装在
pipe()中

或返回高阶函数

private resolveLocationsAndConvertToMarkers = (devices: String[]) => source=>source.pipe(
        tap(_ => this.devicesLoading = true),
        switchMap((devices: string[]) => this.mapService.findLocationForDevices(devices)),
        map(loc => marker([loc.latitude, loc.longitude])
      );

您可以尝试一种反应性方法(除非真正隔离,否则没有副作用):

const preSelection$=this.selection
管
//..自定义映射运算符
();
常量选择$:可观察=预选$.pipe(
开关映射(预选=>
海螺(
of(null),
管道的(预选)(
switchMap(d=>this.mapService.findLocationForDevices(d)),
地图(位置=>标记([位置纬度,位置经度])
)
)
),
shareReplay({bufferSize:1,refCount:true})
);
const isLoading$:Observable=selection$.pipe(映射(x=>!!x));
const sideEffectUpdatePlotMarkers$=selection$.pipe(
轻触(标记=>this.plotMarkers(标记))
);
//尽可能隔离'subscribe'呼叫和副作用
sideEffectUpdatePlotMarkers$.subscribe();

太好了,谢谢你,所有这些都奏效了。为了简单起见,我选择了中间选项。
this.selection
    .pipe.apply(null,this.resolveLocationsAndConvertToMarkers)
  private resolveLocationsAndConvertToMarkers = (devices: String[]) => pipe(
    tap(_ => this.devicesLoading = true),
    switchMap((devices: string[]) => this.mapService.findLocationForDevices(devices)),
    map(loc => marker([loc.latitude, loc.longitude])
  );
private resolveLocationsAndConvertToMarkers = (devices: String[]) => source=>source.pipe(
        tap(_ => this.devicesLoading = true),
        switchMap((devices: string[]) => this.mapService.findLocationForDevices(devices)),
        map(loc => marker([loc.latitude, loc.longitude])
      );
const preSelection$ = this.selection
  .pipe
  //..Custom mapping operators
  ();

const selection$: Observable<Marker> = preSelection$.pipe(
  switchMap(preSelection =>
    concat(
      of(null),
      of(preSelection).pipe(
        switchMap(d => this.mapService.findLocationForDevices(d)),
        map(loc => marker([loc.latitude, loc.longitude]))
      )
    )
  ),
  shareReplay({ bufferSize: 1, refCount: true })
);

const isLoading$: Observable<boolean> = selection$.pipe(map(x => !!x));

const sideEffectUpdatePlotMarkers$ = selection$.pipe(
  tap(markers => this.plotMarkers(markers))
);

// isolate `subscribe` calls and side effects as much as possible
sideEffectUpdatePlotMarkers$.subscribe();