依次处理可观察对象并等待用户输入

时间:2019-01-04 17:21:56

标签: angular typescript rxjs observable ngrx

我需要迭代一系列项目,以检查是否向用户显示模式对话框,并在继续迭代之前等待用户输入。数组包装在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
    }
}

模态本身会返回一个新的可观察值,其中包含用户输入。

我无法确定的是如何在继续可观察数组的迭代,即RxJs方法之前等待模态可观察对象完成。使用诺言链做到这一点不会太令人困惑。

我已经尝试了多种方法,但是现在我可能很难被清楚地看到它所困扰。

我最后一次尝试如下,尽管我很确定这与它的实际情况相去甚远。

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 个答案:

答案 0 :(得分:3)

我认为您已经很接近了,只是做了一些简化:

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