【问题标题】:Emit value then wait for duration before next emission发射值,然后在下一次发射之前等待持续时间
【发布时间】:2020-11-15 04:03:58
【问题描述】:

我正在提供“警报”服务。当有新警报出现时,我想在一段时间内显示警报。在此期间,我不想显示其他可能出现的警报。我只想在当前警报完成后移至下一个警报。所以本质上我想发出该值,然后在发出下一个值之前等待一段时间。

这可以表示为:

const incomingAlerts$ = interval(1000);

const alerts$ = incomingAlerts$.pipe(
  concatMap((alert) => alert.pipe(delay(3500)))
);

这接近我想要的,但延迟会在发出值之前等待。是否有一个运算符或可能的设置会发出该值,然后在发出下一个值之前等待(如果有的话)?

【问题讨论】:

    标签: rxjs rxjs6


    【解决方案1】:

    我认为这可以通过exhaustMap实现:

    incomingAlerts$.pipe(
      exhaustMap(
        alert => NEVER
          .pipe(
            startWith(startAlertAction(alert)),
            takeUntil(duration),
            endWith(stopAlertAction(alert))
        )
      )
    )
    

    使用exhaustMap,除非当前内部可观察对象变为非活动状态(例如completes/发出error 通知),否则不会创建新的内部可观察对象。如果内部 observable 已经处于活动状态,则外部 observable 的值将被忽略。

    【讨论】:

    • 是的,但我不希望这些值被忽略。我想将它们“排队”基本上在一段时间后发出
    • @AveryFerrante 如果在我的示例中用 concatMap 替换exhaustMap 会怎样?
    【解决方案2】:

    你需要做的是创建一个流,它发出一个值,等待一段时间,然后完成。

    这是一种奇怪的做法。你设置了一个timerfilter 输出它的发射。现在你有一个不发出任何内容并在 3500 毫秒内完成的流。然后你startWith你的警报。您可以让concatMap 处理其余的(它将缓冲值直到timer 流完成):

    const alerts$ = incomingAlerts$.pipe(
      concatMap(alert => timer(3500).pipe(
        filter(_ => false),
        startWith(alert)
      ))
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多