【问题标题】:Handle observables in sequence and wait for user input依次处理 observables 并等待用户输入
【发布时间】:2019-01-04 17:21:55
【问题描述】:

我有一个需要迭代的项目数组,以检查是否向用户显示模式对话框,并在继续迭代之前等待用户输入。该数组被包裹在像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();

使用可观察对象处理 “等待用户输入然后继续!” 场景的正确方法是什么?

【问题讨论】:

    标签: angular typescript rxjs observable ngrx


    【解决方案1】:

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

    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 的使用将缓冲传入的通知并等待内部 observable 完成后再继续。

    您的“显示/不显示模态”开关当然必须放入 concatMap 函数中。

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

    【讨论】:

    • 谢谢,这按预期工作!一个后续问题,我将如何等待 concatMap 完成所有项目,然后运行另一个函数?在concatMap 之后将其传递到map 将在每个项目之后运行它,而不是在所有完成之后!
    • 使用长寿的Observable&lt;Array&lt;T&gt;&gt; 不幸的是有点复杂。您必须使用fromfinally 提供不同的mergeMap 函数,concatMap 介于两者之间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多