【问题标题】:RxJS - emit only if other does not emit during delayRxJS - 仅在延迟期间其他不发射时发射
【发布时间】:2019-05-23 04:33:48
【问题描述】:

假设我有两个 observables。每次第一个发射时,我想等待 2 秒,看看在此期间另一个 observable 是否发射了一些东西。如果是,不要发射任何东西。如果没有,发射。

例子:

const start$ = this.events.pipe(
  delay(1000),
  takeUntil(theSecondObservable) // WHAT SHOULD BE HERE?
).subscribe((value) => {
  console.log(value);
});

【问题讨论】:

  • 您的示例正在工作,因为我了解您的问题,我不明白,您的问题是什么?实际上你有 "start$" 和 "theSecondObservable" 是 observable 的,并且你的 "start$" 实际上会在延迟之后发射并且只有当 "theSecondObservable" 没有发射任何东西时才会发射
  • 这是正确的,但我希望每次 start 发出一些东西时都以这种方式发生。这样,直到完成 observable,什么都不会发生。现在清楚了吗?谢谢,
  • 请在帖子下方使用“编辑”在您的帖子中添加说明(尽管我认为您的意思是“......每次 this.events 发出一些东西......”,而不是“......每次开始都会发出一些东西......”)。请进一步澄清:您真的想延迟主要事件还是只是您解决问题的尝试?例如:如果在 1000 毫秒(2000 毫秒)内没有阻塞事件,您是否希望尽快真正发出?您可能还想绘制一个 ASCII 艺术图/时间线。
  • 现在问题清楚了吗?我还提交了我能够用部分答案做出的最终解决方案。

标签: javascript typescript rxjs


【解决方案1】:

当 end$ observable 发出并使用 RxJS 6 语法时,此解决方案不会完成。

const start$ = this.router.events.pipe(map(() => true));
const end$ = this.router.events.pipe(map(() => false));

merge(start$, end$)
  .pipe(debounceTime(2000), filter(value => value))
  .subscribe(value => console.log(value));

如果您要过滤路由器事件,您可能不需要两个 observable。

this.router.events
  .pipe(debounceTime(2000), filter(event => event instanceof NavigationEnd))
  .subscribe(value => console.log(value));

【讨论】:

    【解决方案2】:

    使用race operator

    const start$ = race(this.events.pipe(delay(1000)), theSecondObservable).subscribe(value => /** ... */);
    

    一旦其中一个 observable 发出一个对象,另一个 observable 将被忽略,只有“赢家”发出的值才会传递给订阅者。在您的订阅函数中,您可以执行一些逻辑来确定您的值来自哪个 observable。

    【讨论】:

      【解决方案3】:

      您对限制来自第一个观察者的发射感兴趣还是只对最终结果感兴趣?

      你可以使用比赛...

      let r = race(observer1.pipe(delay(2000)), observer2)
       // r will emmit from observer1 only if observer2 didnt emmit, else it will emmit from observer2
      

      【讨论】:

        【解决方案4】:

        我能够在上面的答案的帮助下解决它。但是,他们并没有完全回答我的问题,可能有更好的方法。我的解决方案:

        const end$ = this.router.events.pipe(
          map(() => false),
        );
        const start$ = this.router.events.pipe(
          map(() => true),
        );
        
        merge(
          end$,
          start$.pipe(
            switchMap(() => {
              return race(end$, of(true).pipe(delay(2000)));
            }),
            filter((value) => value === true) // this really works only with booleans, not sure how I'd do it with more 
                                                                    // complex objects
          )
        ).subscribe((value) => {
          console.log(value);
        });
        

        【讨论】:

        • 看起来合并仍然会从 end$ 发出错误值。
        猜你喜欢
        • 1970-01-01
        • 2021-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多