【问题标题】:How to emit event not earlier than in specified timeout in RXJS?如何在 RXJS 中的指定超时之前发出事件?
【发布时间】:2017-06-29 13:39:54
【问题描述】:

我想在视觉效果消失后发出事件。视觉效果持续 5 秒。 此代码有效,但我认为有更好的解决方案:

Observable.combineLatest(observable1, Observable.of('hold').delay(5000)).subscribe(() => {
    alert('ok');
});

这个事件应该在 observable1 被触发但不早于 5 秒时触发。 (如果 observable1 在 6 秒后触发,则此事件应在 6 秒后触发。如果 observable1 在 3 秒后触发,则此事件应在 5 秒后触发)

【问题讨论】:

    标签: rxjs system.reactive


    【解决方案1】:

    你所描述的看起来你需要withLatestFrom,它只在它的源发射时发射:

    Observable
      .of('hold')
      .delay(5000)
      .withLatestFrom(observable1, (...values) => values[1])
      .subscribe(console.log);
    

    只有延迟的'hold' 字符串控制此运算符何时从Observable1 发出最新值。运算符在其源和Observable1 发出之前不会发出任何东西,所以即使Observable1 在例如之后发出。 6s 您将收到6s 之后的第一个项目。当它反过来并且Observable1 更早发出时,它将等待'hold' 字符串。

    如果您对来自Observable1 的值不感兴趣,您可以忽略投影函数并直接使用:

    ...
    .withLatestFrom(observable1)
    ...
    

    【讨论】:

      【解决方案2】:

      我很抱歉我不是 RxJS 编码器 - 我用 C# 编码。以下是如何在 C# 中执行此操作:

      IObservable<string> query =
          Observable
              .Merge(
                  observable1.Take(1).Select(x => "hold"),
                  Observable.Timer(TimeSpan.FromSeconds(6.0)).Select(x => "hold"))
              .Skip(1);
      

      现在,我可以这样测试:

      var observable1 = new Subject<long>();
      
      IObservable<string> query =
          Observable
              .Merge(
                  observable1.Take(1).Select(x => "hold"),
                  Observable.Timer(TimeSpan.FromSeconds(6.0)).Select(x => "hold"))
              .Skip(1);
      
      Console.WriteLine(DateTime.Now);
      query.Subscribe(x => Console.WriteLine(DateTime.Now));
      
      Thread.Sleep(1000); // 1 second
      observable1.OnNext(42);
      

      产生:

      2017/06/30 17:04:57 2017/06/30 17:05:03

      将测试代码改为:

      Thread.Sleep(6000); // 6 seconds
      observable1.OnNext(42);
      

      你会得到:

      2017/06/30 17:08:49 2017/06/30 17:08:55

      最后把测试代码改成:

      Thread.Sleep(10000); // 10 seconds
      observable1.OnNext(42);
      

      你会得到:

      2017/06/30 17:09:27 2017/06/30 17:09:37

      如果你想要的话,请告诉我。

      有人可以编辑我的答案以将我的代码更改为 RxJS 吗?

      【讨论】:

        【解决方案3】:

        observableInstance.delay怎么样?

        observable1.delay(5000).subscribe(() => {
            alert('ok');
        });
        

        【讨论】:

        • 我更新了问题。此事件应在 observable1 被触发但不早于 5 秒时触发。在您的情况下,如果 observable1 在 6 秒后触发,则此事件将在 11 秒后触发。在这种情况下,我需要 6 秒。
        【解决方案4】:

        Rx.js debounceTime 运算符仅在指定时间过去后才从源 observable 发出最新值。

        Observable1.debounceTime(5000).subscribe(() => { alert('ok') } );
        

        【讨论】:

          【解决方案5】:
          observable1.combineLatest(Observable.timer(5000))
              subscribe(([result]) => {
                  alert('ok');
              });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-03
            • 2014-11-08
            • 2022-01-27
            • 1970-01-01
            相关资源
            最近更新 更多