【问题标题】:Angular: merge more than 6 observables?Angular:合并超过 6 个 observables?
【发布时间】:2021-05-05 09:06:26
【问题描述】:

我试图在我的合并中添加另一个 observable,所以从正确的开始

return merge(   
          this.paginator.page, this.sort.sortChange, 
          this.cmdtyChanges.pipe(map(cmdties =>{
            return {'cmdties': cmdties};})), 
          this.bookChanges.pipe(map(book =>{
            return {'book': book};})), 
          this.start.pipe(map(update => {
            return {'start':update};})), 
          this.end.pipe(map(update => {
            return {'end':update};})))

我想像下面这样添加另外两个

  return merge(   
      this.paginator.page, this.sort.sortChange, 
      this.cmdtyChanges.pipe(map(cmdties =>{
        return {'cmdties': cmdties};})), 
      this.bookChanges.pipe(map(book =>{
        return {'book': book};})), 
      this.cptyChanges.pipe(map(cpties =>{
        return {'cpties': cpties};})),
      this.traderChanges.pipe(map(traders =>{
        return {'traders': traders};})),
      this.start.pipe(map(update => {
        return {'start':update};})), 
      this.end.pipe(map(update => {
        return {'end':update};})))

但它不能编译超过 6 个...

如何绕道?

编辑

抱歉编辑,但看到答案后,我想我必须在合并后显示管道

所以我在做

.pipe(map((merged) => {
          var mustLoad = false;
          if ('book' in merged) {
            this.sendMessage(`book selected: ${merged.book}`);
            this.selBook = merged.book;
          }
          if ('traders' in merged) {
            this.sendMessage(`traders selected: ${merged.traders.length}`);
            this.selTraders = merged.traders;
            console.log('current traders', this.selTraders);
          }

当我传递超过 6 种不同类型 Observable<...> | Observable<...> | ... 的联合时,.pipe(map((merged) => {merged 的类型变得未知,之后的代码无法编译

【问题讨论】:

    标签: angular typescript rxjs observable


    【解决方案1】:

    RxJS 只为有限数量的组合准备了类型。因此,如果您有超过 6 个源 Observable,您可以先创建一个 Observable 数组,然后使用扩展运算符 (...) 将它们传递给 merge()

    const sources = [
      this.paginator.page,
      this.sort.sortChange,
      // other-sources,
    ];
    
    merge(...sources).subscribe();
    

    带有 7 个源 Observable 的演示:https://stackblitz.com/edit/rxjs-luldtu?devtoolsheight=60

    【讨论】:

    • 但我认为它不起作用:我想问题是它最终无法识别合并结果的类型......由于事实,它不会编译错误合并类型未知
    • 这应该也可以,或者您可以使用自己的类型与merge<A | B | C | D | E | F | more>() 我猜。 merge() 应该创建一个所有类型的联合。
    • 也许我对打字稿太无知了我说merge<A | B | C | D | E |F | G>(7种不同类型的联合)在合并时无法编译(或导致未知类型)(6 种不同类型的联合)可以。让我编辑我的问题以在合并后显示管道
    • 我试过了,它需要有点不同。 merge() 总是返回 unknown 所以你需要自己输入这个,看这个stackblitz.com/edit/rxjs-luldtu?devtoolsheight=60
    • 好的,我将使用 interface MyChange { myvalue: string, mytype: string } 。如果可以,请更新您的答案以反映这一点,以便我接受。你现在写的没有任何效果。此外请注意merged 的类型变为unknown only超过 6 个不同的 observables。提前谢谢你
    【解决方案2】:

    根据我的评论,我发现使用扩展运算符会使结果始终未知,而如果我保持在 6 个不同的 observables 之下,我可以正确键入它。另请注意,由于merge 的签名在那里不兼容,因此该问题在 stackblitz 上无法完全重现。

    因此,我为可简化为的情况实施了内部合并

    interface MyChange {
      myvalue: string[], mytype: 'traders'|'cpties'|'cmdties'
    } 
    

    并且 - 尽可能避免类型断言以保持类型安全 - 我将整个包装合并管理为

      return merge(
        this.paginator.page,
        this.sort.sortChange,
        this.bookChanges.pipe(map(book => {
          return { 'book': book };
        })),
    
        (merge(this.cmdtyChanges.pipe(map(cmdties => {
          const ret : MyChange = { 'myvalue': cmdties, 'mytype': 'cmdties' };
          return ret;
        })),
          this.cptyChanges.pipe(map(cpties => {
          const ret : MyChange =  { 'mytype': 'cpties', 'myvalue': cpties };
          return ret;
          })),
          this.traderChanges.pipe(map(traders => {
          const ret : MyChange =  { 'mtyype': 'traders', 'myvalue': traders };
          return ret;
          })))   ),
    
        this.start.pipe(map(update => {
          return { 'start': update };
        })),
        this.end.pipe(map(update => {
          return { 'end': update };
        }))
      )
    

    以这样一种方式,我终于可以将安全输入的 - 不是未知的 - 结果通过管道传输到

        .pipe(map((merged ) => {
          var mustLoad = false;
          if ('book' in merged) {
            this.sendMessage(`book selected: ${merged.book}`);
            this.selBook = merged.book;
          }
          if ('mytype' in merged && merged.mytype == 'traders') {
            this.sendMessage(`traders selected: ${merged.myvalue.length}`);
            this.selTraders = merged.myvalue;
            console.log('current traders', this.selTraders);
          }
    

    等等……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多