Angular Rxjs:使用管道运算符的语法错误

时间:2019-05-09 08:20:13

标签: angular typescript rxjs

我正在尝试重新编写以下代码:

Observable
    .merge(this.searchQuery$, this.lazyQuery$)
    .do(() => this.loadingPage())
    .map(filter => this.buildURL("jaume", Config.security['appName'], filter))
    .switchMap(url =>
        this.service.getItemsFromStorage(url)
        .map(response => this.buildPage(response))
        .catch(() => Observable.of(pojo.Page.EMPTY))
    )
    .do(page => this.loadedPage(page))
    .takeUntil(this.unsubscribe$)
    .subscribe();

我想使用“ pipable”语法。到目前为止,我已经能够这样写了:

this.searchQuery$.pipe(
    merge(this.lazyQuery$),
    tap(() => this.loadingPage()),
    map(filter => this.buildURL("jaume", Config.security['appName'], filter))
)
.pipe(
    switchMap(url => this.service.getItemsFromStorage(url)),
    catchError(() => Observable.of(pojo.Page.EMPTY))
)
.pipe(
    tap(page => this.loadedPage(page))  <<***>>
);

我在<<***>>上遇到编译器错误:

  

“ Response |类型”的参数“页面”不可分配给“页面”类型的参数。     类型“响应”缺少类型“页面”中的以下属性:总计,用户

似乎catchError返回{} | Page类型时,它应该返回单个Page类型。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您错过了将response映射到page的问题。

merge(this.searchQuery$, this.lazyQuery$).pipe(
  tap(() => this.loadingPage()),
  map(filter => this.buildURL("jaume", Config.security['appName'], filter)),
  switchMap(url => this.service.getItemsFromStorage(url).pipe(
    map(response => this.buildPage(response)), // <-- you missed this map in your code
    catchError(() => of(pojo.Page.EMPTY))
  )),
  tap(page => this.loadedPage(page)),
  takeUntil(this.unsubscribe$)
).subscribe();

也请查看官方迁移指南:Howto: Convert to pipe syntax

答案 1 :(得分:1)

首先,管道过多。不需要那么多。另外,您可以使用of()而不是Observable.of()来代替this.searchQuery$.pipe( merge(this.lazyQuery$), tap(() => this.loadingPage()), map(filter => this.buildURL("jaume", Config.security['appName'], filter)), switchMap(url => this.service.getItemsFromStorage(url)), catchError(() => of(pojo.Page.EMPTY)), tap(page => this.loadedPage(page)) <<***>> ); ,因为它更短,恕我直言,更易于阅读。

...
catchError(() => of(<Page>pojo.Page.EMPTY))
...

这将正常工作。

您的错误并不关乎它返回什么,而是它返回的TypeScript 认为。因此,您只需要说它返回的内容即可。例如

catchError

如果这确实与... switchMap(() => of(null).pipe( catchError(...) )) 部分有关。

更新#1-嵌套

如果需要将某些特定的管道应用于链中的仅一个点,则应将此管道添加到返回可观察到的位置。例如

.pipe(...),
.pipe(...),
.pipe(...),

这样做的时候

.pipe(
...
...
...
)

这等效于

In file included from ./tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8.h:22:0,
                 from tensorflow/lite/kernels/depthwise_conv.cc:29:
./tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8_3x3_filter.h: In static member function ‘static void tflite::optimized_ops::depthwise_conv::WorkspacePrefetchWrite<(tflite::DepthwiseConvImplementation)3>::Run(int8, int, int8*)’:
./tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8_3x3_filter.h:5782:71: note: use -flax-vector-conversions to permit conversions between vectors with differing element types or numbers of subparts
       vst1_lane_u32(reinterpret_cast<uint32_t*>(ptr), fill_data_vec, 0);
                                                                       ^
./tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8_3x3_filter.h:5782:71: error: cannot convert ‘const int8x8_t {aka const __vector(8) signed char}’ to ‘uint32x2_t {aka __vector(2) unsigned int}’ for argument ‘2’ to ‘void vst1_lane_u32(uint32_t*, uint32x2_t, int)’
./tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8_3x3_filter.h:5785:35: error: cannot convert ‘const int8x8_t {aka const __vector(8) signed char}’ to ‘uint32x2_t {aka __vector(2) unsigned int}’ for argument ‘2’ to ‘void vst1_lane_u32(uint32_t*, uint32x2_t, int)’
                   fill_data_vec, 0);
                                   ^
tensorflow/lite/tools/make/Makefile:225: recipe for target '/tensorflow/tensorflow/lite/tools/make/gen/aarch64_armv8-a/obj/tensorflow/lite/kernels/depthwise_conv.o' failed
make: *** [/tensorflow/tensorflow/lite/tools/make/gen/aarch64_armv8-a/obj/tensorflow/lite/kernels/depthwise_conv.o] Error 1
make: *** Waiting for unfinished jobs....