代码之家  ›  专栏  ›  技术社区  ›  Daniel B

按顺序处理观察值并等待用户输入

  •  0
  • Daniel B  · 技术社区  · 7 年前

    我有一个项目数组,需要迭代以检查是否向用户显示模式对话框,并等待用户输入,然后再继续迭代。数组被包裹在一个可观察的类 Observable<Array<Item>>; .

    对于数组中的每个项,我需要检查它的类型是否已存在于 Map<ItemType, string> 对象如果不存在,则应显示用户输入注释的模式,并将输入值存储在地图中。如果存在,则不应执行任何操作,迭代应继续。我已经写了一些伪代码来实现下面的目标。

    Map<ItemType, string> comments;
    Observable<Array<Items>> items;
    
    foreach (item in items) {
        if(comments[item.type]) {
            continue to next item;
        } else {
            show a modal dialog and wait for the userInput;
            onModalClose -> comments[item.type] = userInput
        }
    }
    

    模态本身返回一个新的可观察到的用户输入。

    . 用承诺链做这件事不会太令人困惑。

    我尝试过多种方法,但现在我可能会被我想清楚地看到它的尝试弄糊涂了。

    我的最后一次尝试如下所示,尽管我非常确定这与它应该是什么样子相去甚远。

    this.items$.pipe( //Observable<Array<Item>>
          map(items => items.map(i => of(i))), //Convert to an Array<Observable<Item>>
          switchMap(items => { 
            return concat(...items).pipe(
              switchMap(item => {
                return this.showExtraInformationModal().pipe(
                  map(resultFromModal => {
                    // Use the result from modal 
                  })
                );
              })
            )
          })
        ).subscribe();
    

    正确的处理方法是什么 “等待用户输入,然后继续!” 可观测情景?

    1 回复  |  直到 7 年前
        1
  •  4
  •   ggradnig    7 年前

    我认为你很接近,只是一些简化:

    items$.pipe(
      mergeMap(items => items), //converts Observable<Array<T>> to a stream of T
      concatMap(item => 
        item.showModal ?
          showExtraInformationModal().pipe(
            map(resultFromModal => {
              // Use the result from modal 
            }))
          :
          of(item)
      )
    ).subscribe();
    

    使用 concatMap

    当然,必须将“显示/不显示模式”开关置于concatMap功能中。

    演示: https://stackblitz.com/edit/rxjs-sxeude?file=index.ts